eval命令的作用是读取参数,并依照参数本身的特性执行。或者说eval强制Shell对命令行进行两次扫描,执行变量或命令替换。
读取参数,并依照参数本身的特性执行。
eval [param]
我们先来看一个例子:
[peter@ibi98 shell]$ a=protein [peter@ibi98 shell]$ b="$"a [peter@ibi98 shell]$ echo $b $a [peter@ibi98 shell]$ eval echo $b protein [peter@ibi98 shell]$ eval echo "$"b $a
上例中,给变量b赋值时,Shell对"$"a进行一边扫描,将$和a连起来,作为一个字符串赋值给b。所以变量b的值是字符串$a,而不是变量a的值。使用eval命令后,Shell再进行第二次变量替换,将$a替换成变量a的值,也就是protein,所以输出的是protein。最后一个命令中,Shell第一次扫描,变成eval echo $b,第二次扫描将$b替换成变量b的值,也就是$a,然后输出,也就是说使用eval后,Shell对命令行进行两遍扫描。Shell扫描次数不同,会输出不同的结果:
命令行结束符(;)、管道符(|)、后台命令符(&)、重定向符(< >)和引号对Shell具有特殊意义,必须直接出现在命令行中。如果这些符号包含在变量里,Shell在变量扩展后将这些符号作为普通字符,从而引起错误,这时就可以用eval对命令行进行二次扫描,使命令正确执行。如:
[peter@ibi98 shell]$ a="ls |grep test" [peter@ibi98 shell]$ echo $a ls |grep test [peter@ibi98 shell]$ $a #变量扩展后,Shell将|grep当成文件名 ls: 无法访问|grep: 没有那个文件或目录 test: tmp [peter@ibi98 shell]$ eval $a #eval强制Shell对命令行进行两次扫描,识别出管道符 test test.sh