'eval $command' 和 $command 有什么区别?

What's the difference between 'eval $command' and $command?

有什么区别:

eval echo lala

和:

command="echo lala"
$command

它们似乎都具有相同的效果,但我可能遗漏了一些东西。另外,如果它们 do 具有相同的效果,那么 eval 命令的意义何在?

试试这个:

y='FOO=hello; echo $FOO'
eval $y

它打印 hello.

但是这个:

$y

说:

-bash: FOO=hello;: command not found

所以当你说 eval $y 就好像你在解释器中输入了 $y 的内容一样。但是当你只是说$y时,它需要是一个可以是运行的命令,而不是解释器需要解析的一些其他标记(在上面的例子中,变量赋值)。

如果您知道一个变量包含一个可执行命令,您可以 运行 它而不用 eval。但是,如果变量可能包含 Bash 代码,这不仅仅是一个可执行命令(即您可以想象传递给 C 函数 exec() 的东西),则需要 eval.

要扩展@JohnZwinck 的伟大 ,请同时查看这些示例:

command='ls | wc -l'
eval $command
# outputs the correct result => 17
$command
ls: -l: No such file or directory
ls: wc: No such file or directory
ls: |: No such file or directory

command='ls -l $PWD'
eval $command
# outputs the contents of current directory
$command
# runs 'ls -l $PWD' literally as a command and ls tries to lookup $PWD as a file
ls: $PWD: No such file or directory

因此,eval 内置函数以与 shell 相同的方式解释其参数。但是,在 $command 的情况下,shell 扩展变量并将内容按字面意思视为命令。