2
x="a=b"
`echo $x`
echo $a

我希望第二行生成“a=b”,并在主 shell 的上下文中执行它,从而产生一个a带有 value的新变量b。但是,我真正得到的(如果我手动输入命令)是第二行之后的错误消息,bash: a=b: command not found

为什么呢?

4

4 回答 4

4

尝试

eval $x

(我们需要 30 个字符才能发布此答案)

于 2012-02-16T09:07:54.857 回答
3

您的第一个回显行所做的是在子shell 中运行并将其值返回给被调用者。使用相同的结果可以实现$(),并且 - 顺便说一下 - 比反引号更易于使用。

所以,你正在做的是首先运行echo $x(返回a=b)。并且,由于反引号,a=b返回到尝试将该行作为命令运行的 shell - 显然 - 将不起作用。

在 shell 中试试这个:

$(echo ls)

你会清楚地看到正在发生的事情。

于 2012-02-16T09:53:32.680 回答
1

这是因为 bash 解析命令行的顺序。它在执行变量和命令替换(例如反引号中的命令a=b之前查找变量定义(例如)。正因为如此,当时间echo $x被替换为a=b时,bash 将其视为变量定义而将其解析为命令为时已晚。$x如果您只是用作命令(而不是反引号中的 echo),也会发生同样的事情。正如@mvds 的回答一样,该eval命令可用于强制从头开始重新解析命令,这意味着它将被识别为变量定义:

$ x="a=b"
$ `echo $x`
-bash: a=b: command not found
$ $(echo $x)  # Exact same thing, but with cleaner syntax
-bash: a=b: command not found
$ $x  # This also does the same thing, but without some extra steps
-bash: a=b: command not found
$ eval "$x"  # This will actually work
$ echo $a
b
$ a=  # Start over
$ eval "$(echo "$x")"  # Another way of doing the same thing, with extra steps
$ echo $a
b

请注意,在使用时,eval我已将所有引用$x放在双引号中 - 这是为了防止 bash 解析的后期阶段(例如分词)发生两次,因为 bash 将完成其常规解析过程,然后识别eval命令,然后再次重做整个解析过程。使用 很容易得到意想不到的结果eval,这至少消除了一些潜在的麻烦。

于 2012-02-16T19:13:57.503 回答
0

你试过$x那些有趣的撇号吗?没有echo, echo 似乎仅用于显示字符串,而不是执行命令。

于 2012-02-16T09:06:05.390 回答