“eval $command”和“$command”有什么区别?

5

以下是“什么是……”和“如何使用……”的区别:

eval echo lala

并且:

command="echo lala"
$command

它们似乎具有相同的效果,但我可能漏掉了某些东西。另外,如果它们确实具有相同的效果,那么使用eval命令的意义是什么?

2个回答

10

试一试:

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

它打印出hello

但是这个:

$y

说:

-bash:FOO = hello;:未找到命令

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

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


我认为单个命令是实际的Bash代码,因此也许有更好的方法来描述你的意思(尽管我不确定该如何表达,这就是为什么我放弃回答的原因!) - Tom Fenech
2
@TomFenech:确实措辞不当,我已经更改了。 - John Zwinck

4

为了扩展@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会扩展变量并将内容字面上视为命令。

请注意,在我的问题中使用''而不是""时,ls -l $PWD无法正常工作。 - NPS
2
当您使用 "" 时,PWD 变量会在分配给 command 时进行扩展。它不会在通过 $command 执行期间进行扩展。 - codeforester
嗯,显然是这样的。但我实际上没有想到 eval 会将 '' 吞掉,并且还会扩展变量。所以谢谢。 - NPS
1
eval 不会“吃掉”单引号;在 eval 运行之前,shell 会先将它们移除。 - chepner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接