我正在尝试一些非常简单的方法:
PEOPLE=(
"nick"
"bob"
)
export PEOPLE="$(IFS=, ; echo "${PEOPLE[*]}")"
echo "$PEOPLE" # prints 'nick,bob'
./process-people.sh
由于某些原因,process-people.sh
没有看到$PEOPLE
。与之类似,如果我从echo "$PEOPLE"
内部process-people.sh
来打印空白行。
据我了解,通过调用./process-people.sh
创建的子进程应该继承所有父进程的环境变量,包括$PEOPLE
。
但是,我已经在Bash 3.2.57(1)-发行版和4.2.46(2)-发行版上进行了尝试,但这不起作用。
这是怎么回事?
答案 0 :(得分:3)
对于joining the elements of a Bash array into a string,这是一个很好的解决方案。您是否知道在Bash中您cannot export array variables to the environment?如果环境中没有变量,则子进程将看不到它。
啊。但是,您不是要导出数组,而是。您正在将数组转换为字符串,然后将其导出。所以应该可以。
但这是Bash!在各种历史事故共同企图的地方。
正如@PesaThe和@chepner在下面的注释中指出的那样,您实际上不能将Bash数组变量转换为字符串变量。根据{{3}}:
引用没有下标的数组变量等效于引用下标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[*]
)的陷阱。