Bash:用多个未设置/导出命令替换命令

Bash:用多个未设置/导出命令替换命令

我正在尝试取消设置一些变量并使用命令替换导出其他变量。这有效:

$(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_Aexport TEST_B=1(同样,两个简单的命令)。

相关内容