eval可以读取一连串的参数,然后按照参数特性来执行。参数数目不限,彼此之间用分号隔开。
eval会对后面的命令进行两遍扫描,如果第一遍扫描后,命令是个普通命令,则执行此命令;如果命令中含有变量的间接引用,则保证间接引用的语义。也就是说,eval命令将会首先扫描命令行进行所有的置换,然后再执行该命令。因此,eval命令适用于那些一次扫描无法实现其功能的变量。
eval 执行以下两个步骤:
第一步,执行变量替换,类似与C语言的宏替代;
第二步,执行替换后的命令串。
下面看几个例子:
X=10 Y=X echo '$'$Y eval echo '$'$Y
输出如下:
$X
10
[kumufengchun@localhost ~]$ vim test.sh [kumufengchun@localhost ~]$ WORD="cat test.sh" [kumufengchun@localhost ~]$ echo $WORD cat test.sh [kumufengchun@localhost ~]$ eval $WORD Hello World
这些需要进行两次扫描的变量有时被称为复杂变量。不过这些变量本身并不复杂。eval命令不仅可以回显复杂变量,也可以用于回显简单变量。
[kumufengchun@localhost ~]$ NAME=filename [kumufengchun@localhost ~]$ echo $NAME filename [kumufengchun@localhost ~]$ eval echo $NAME filename
在编写shell脚本的时候也会经常出现“/bin/grep: |: No such file or directory”类似的错误,特别是在执行的命令是变量的情况
[root@bogon script]# cat aa.sh aa="/bin/grep Accepted /root/test.log | /bin/grep -v something" tmp=`$aa` [root@bogon script]# bash aa.sh /bin/grep: |: No such file or directory /bin/grep: something: No such file or directory
解决方法可以使用eval命令
[root@bogon script]# cat aa.sh aa="/bin/grep Accepted /root/test.log | /bin/grep -v something" tmp=`eval $aa` [root@bogon script]# bash aa.sh [root@bogon script]# [root@bogon script]#
[root@bogon script]# cat dd.sh X=10 Y=X echo '$'$Y echo $$Y echo ${$Y} eval echo '$'$Y [root@bogon script]# bash dd.sh $X 40342Y dd.sh: line 5: ${$Y}: bad substitution 10