这是我的(不工作)设置:
one.sh:
#!/bin/bash -x
MYFLAGS="FLAG=foo"
echo ${MYFLAGS} | ${MYFLAGS} ./two.sh
two.sh:
#!/bin/bash -x
echo $FLAG
输出:
>> one.sh
+ MYFLAGS=FLAG=foo
+ echo FLAG=foo
+ FLAG=foo ./two.sh
./one.sh: line 5: FLAG=foo: command not found
如何将列表(在此casse中只包含一个元素)传递给第二个脚本two.sh
?我知道,我可以使用export FLAG
使其可用,但我想避免这种情况。
答案 0 :(得分:3)
Shell变量可以包含任意C字符串,因此可以包含除NUL之外的任何字符。因此,您可能放在包含多个其他变量的变量中的任何字符也可能是有效值,因此用作通用分隔符是不安全的。
有一些相当简单的方法可以绕过这个:
一些更明显的编码方法需要在解码时使用eval
。这incurs security risks,因此不赞成。 Workarounds to read eval
-style data formats存在,但有些存在重大错误/限制(xargs
解析bash的字符串文字格式的子集,但不解析完整集。)
选择以下方法以允许表示所有可能的值,并避免任何安全问题。
发出NUL分隔的key=value
对流(请注意,您无法将其保存在单个变量中 - 因为NUL终止了值并且文字NUL无法识别存储在字符串中 - 但您可以将其传递给文件描述符):
emit_variables() {
local var
for var; do
printf '%q=%s\0' "${var}" "${!var}"
done
}
消费它:
read_variables() {
local varspec
while IFS= read -r -d '' varspec; do
name=${varspec%%=*}
value=${varspec#*=}
printf -v "$name" '%s' "$value"
done
}
因此:
# make both these functions available through the environment
export -f emit_variables read_variables
foo=$'bar\nbaz' bar='baz=qux'
emit_variables foo bar | bash -c 'read_variables; declare -p foo bar'
...将正确发出:
declare -- foo="bar
baz"
declare -- bar="baz=qux"
将内容存储在变量中需要以不会干扰NUL的方式转义数据。例如:
export variable_state=$(emit_variables foo bar | openssl enc -base64)
......而且,这是你的消费者:
read_variables < <(openssl enc -base64 -d <<<"$variable_state")