使用"评估$cmd"和仅使用"$cmd"之间的bash有什么区别吗?



在 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有所作为的情况?性能如何?

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

cmd="echo -n sometext"
eval $cmd 

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

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

在这里,首先$cmd首先被评估,然后将整个字符串作为参数传递给 eval 命令。然后 eval 计算命令,将第一个参数视为"命令或可执行文件",然后作为普通命令运行。因此,这里要执行 2 轮评估以执行完整的命令。 (注意:上面的+符号显示了在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

我希望解释会有所帮助。

最新更新