使用`eval $ cmd`和'$ cmd`之间的bash有什么不同吗?

时间:2018-03-11 12:41:07

标签: bash eval

在bash中,您可以通过两种不同的方式将字符串视为命令(并运行它):

#!/bin/bash
cmd="echo -n sometext"
eval $cmd    # Not sure if quotes make a difference here

#!/bin/bash
cmd="echo -n sometext"
$cmd    # Not sure if quotes make a difference here either

这两者有什么区别吗?是否存在cmd周围的引号有所不同的情况?性能怎么样?

1 个答案:

答案 0 :(得分:3)

是的,有区别:) 您需要先了解eval的工作原理。基本上,eval是shell内置命令。传递给eval的任何参数首先被视为字符串。 让我们举个例子:

 cmd="echo -n sometext"
 eval $cmd 

此命令的完整运行过程如下:

 eval $cmd
 + eval echo -n sometext
 ++ echo -n sometext
 sometext

这里,首先评估$ cmd,然后将整个字符串作为参数传递给eval命令。然后,eval将该第一个参数作为"命令或可执行文件"来评估该命令。然后作为正常命令运行。因此,这里有两轮评估,用于执行完整命令。 (注意:上面的+符号表示在bash -x模式下使用时逐步执行)

主要后果在于可变扩张。 eval我们有两轮扩张。当然,一个是定义cmd时,一个是eval执行时。

var="inital"
cmd="echo -n $var \$var"
var="chanded in the mean time"
eval $cmd
inital chanded in the mean time

但是,当你只使用$cmd而没有eval时,bash负责从变量扩展到最终执行的所有事情。只运行$cmd

时,只需查看调试窗口详细信息
$cmd
+ echo -n sometext
sometext

性能方面,直接使用$cmd就足够了。但是,当您尝试使用某些外部命令或需要更改环境的脚本时,可以使用eval

cmd="echo -n sometext"中,引号是必要的,否则在" echo"之后,bash会引发如下错误:

cmd=echo -n sometext
-n: command not found

我希望这些解释会有所帮助。