调用存储在变量中的某些命令的正确方法是什么?
1和2有区别吗?
#!/bin/sh
cmd="ls -la $APPROOTDIR | grep exception"
#1
$cmd
#2
eval "$cmd"
调用存储在变量中的某些命令的正确方法是什么?
1和2有区别吗?
#!/bin/sh
cmd="ls -la $APPROOTDIR | grep exception"
#1
$cmd
#2
eval "$cmd"
Unix shell 在执行它们之前对每一行输入进行一系列转换。对于大多数 shell,它看起来像这样(取自Bash 手册页):
在参数扩展阶段,直接使用$cmd
会将其替换为您的命令,然后进行所有以下转换。
usingeval "$cmd"
直到引号删除阶段才执行任何操作, where$cmd
按原样返回,并作为参数传递给eval
,其功能是在执行之前再次运行整个链。
所以基本上,它们在大多数情况下是相同的,并且当您的命令使用到参数扩展的转换步骤时它们会有所不同。例如,使用大括号扩展:
$ cmd="echo foo{bar,baz}"
$ $cmd
foo{bar,baz}
$ eval "$cmd"
foobar foobaz
如果你只是在我们做的eval $cmd
时候做cmd="ls -l"
(交互地和在脚本中),你会得到想要的结果。在您的情况下,您有一个带有 grep 没有模式的管道,因此 grep 部分将失败并显示错误消息。只是$cmd
会生成“找不到命令”(或类似的)消息。
因此,请尝试使用eval(在"The args are read and concatenated together"附近)并使用已完成的命令,而不是生成错误消息的命令。
$cmd
只需将变量替换为要在命令行上执行的值。
eval "$cmd"
在命令行上执行结果值之前进行变量扩展和命令替换
当您想运行不灵活的命令时,第二种方法很有帮助,例如。
for i in {$a..$b}
格式循环不起作用,因为它不允许变量。
在这种情况下,连接到 bash 或 eval 的管道是一种解决方法。
在 Mac OSX 10.6.8、Bash 3.2.48 上测试
我认为你应该把
`
变量周围的(反引号)符号。