题
x="a=b"
`echo $x`
echo $a
我希望第二行生成“ a = b”,并在主壳的上下文中执行它,从而导致新变量 a
有价值 b
。但是,我真正得到的(如果我手动输入命令)是第二行之后的错误消息, bash: a=b: command not found
为什么呢?
解决方案
这是因为Bash解析命令行的顺序。它寻找可变定义(例如 a=b
) 前 执行变量和命令替换(例如,在Backticks中命令)。因此,到了 echo $x
被取代 a=b
, ,Bash将其视为可变定义为时已晚,而将其解析为命令。如果您只使用 $x
作为命令(而不是回声中的回声)。如 @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
, ,这至少消除了一些麻烦的潜力。
其他提示
尝试
eval $x
(我们需要30个字符才能发布此答案)
您的第一条回声线所做的是在子壳中运行,并将其值返回到Callee。 $()
顺便说一句 - 比背部更易于使用。
因此,您正在做的是首先运行 echo $x
(返回 a=b
)。而且,由于背景 a=b
将返回到试图运行该行作为命令的外壳,显然 - 不起作用。
在外壳中尝试一下:
$(echo ls)
您将清楚地看到正在发生的事情。
你试过了吗 $x
在那个有趣的撇号中?没有 echo
, ,Echo似乎仅用于显示字符串,而不是执行命令。
不隶属于 StackOverflow