对于joining the elements of a Bash array into a string,这是一个很好的解决方案。你知道在 Bash 你cannot export array variables to the environment 吗?而如果一个变量不在环境中,那么子进程将看不到它。
啊。但是您不是在导出数组,是吗。您正在将数组转换为字符串,然后将其导出。所以它应该可以工作。
但这是 Bash!各种历史事故合力让你指手画脚。
正如@PesaThe 和@chepner 在下面的 cmets 中指出的那样,您实际上无法将 Bash 数组变量转换为字符串变量。根据Bash reference on arrays:
引用不带下标的数组变量等价于引用下标为 0。
因此,当您调用 export PEOPLE=... 之前为 PEOPLE 分配了一个数组值时,您实际执行的是 PEOPLE[0]=...。这是一个更完整的例子:
PEOPLE=(
"nick"
"bob"
)
export PEOPLE="super"
echo "$PEOPLE" # masks the fact that PEOPLE is still an array and just prints 'super'
echo "${PEOPLE[*]}" # prints 'super bob'
不幸的是,export 默默地无法将数组导出到环境中(它返回0),而且在某些情况下,Bash 将ARRAY_VARIABLE 等同于ARRAY_VARIABLE[0] 令人困惑。我们只需要把它归结为历史和向后兼容性的结合。
这是解决您的问题的有效解决方案:
PEOPLE_ARRAY=(
"nick"
"bob"
)
export PEOPLE="$(IFS=, ; echo "${PEOPLE_ARRAY[*]}")"
echo "$PEOPLE" # prints 'nick,bob'
./process-people.sh
这里的关键是将数组和派生字符串分配给不同的变量。 由于PEOPLE 是一个正确的字符串变量,它可以很好地导出,process-people.sh 将按预期工作。
无法将 Bash 数组变量直接更改为字符串变量。一旦一个变量被赋予了一个数组值,它就变成了一个数组变量。将其改回字符串变量的唯一方法是使用 unset 销毁它并重新创建它。
Bash 有几个方便的命令用于检查变量,这些命令对于调查这类问题很有用:
printenv PEOPLE # prints 'nick,bob'
declare -p PEOPLE_ARRAY # prints: declare -ax PEOPLE_ARRAY='([0]="nick" [1]="bob")'
printenv 只会返回环境变量的值,而echo 将打印结果,无论变量是否已正确导出。
declare -p 将显示变量的完整值,而不会出现与包含或省略数组索引引用相关的问题(例如 ARRAY_VARIABLE[*])。