![Bash:用多个未设置/导出命令替换命令](https://linux22.com/image/47123/Bash%EF%BC%9A%E7%94%A8%E5%A4%9A%E4%B8%AA%E6%9C%AA%E8%AE%BE%E7%BD%AE%2F%E5%AF%BC%E5%87%BA%E5%91%BD%E4%BB%A4%E6%9B%BF%E6%8D%A2%E5%91%BD%E4%BB%A4.png)
我正在尝试取消设置一些变量并使用命令替换导出其他变量。这有效:
$(echo "
export TEST_A=1
export TEST_B=2
")
还有这个:
$(echo "
unset TEST_A
unset TEST_B
")
然而,在 OSX 和 Debian Jessie 上的 Bash 4.3.30(1)-release 上这都会失败:
$(echo "
unset TEST_A
export TEST_B=1
")
# bash: unset: `TEST_B=1': not a valid identifier
这是预期的行为吗?如何使用命令替换取消设置和导出多个变量?
提供一些背景:这是相关的boot2docker 中的问题。
答案1
在:
$(echo "
export TEST_A=1
export TEST_B=2
")
,只有$(...)
一个扩展被解析为一个简单的命令。
因此该$(...)
扩展经历了 split+glob 运算符。的输出echo
被修剪掉其尾随换行符,并在 IFS 字符上分成几个单词(默认情况下为换行符、空格和制表符):
export
TEST_A=1
export
TEST_B=2
每个单词都会经历通配符。在这里,它们扩展为自身,因为它们不包含通配符。所以在通配之后,我们仍然有相同的四个字符串列表。
要运行的命令源自第一个命令。这里export
和所有这些字符串都作为参数传递给该命令。所以,在这里,就好像你写了:
export TEST_A=1 export TEST_B=2
因此,您要导出TEST_A
值为 1 的变量、export
不更改其值的变量以及TEST_B
值为 2 的变量。
在最后一项中,您正在运行:
unset TEST_A export TEST_B=1
如果您希望将 的输出echo
视为 shell 代码来解释,那么您需要使用eval
和不使用分割+全局运算符(引用您的命令替换):
eval "$(echo "
unset TEST_A
export TEST_B=1
")"
那个也是一个简单的命令。两个字符串:eval
和<newline><spaces>unset TEST_A<newline><spaces>export TEST_B=1
。
eval
将其参数的内容计算为 shell 代码。所以它运行这两个 shell 命令行:unset TEST_A
和export TEST_B=1
(同样,两个简单的命令)。