这个命令,平时接触不是很多,所以不知道是什么回事。
eval内置命令:
功能:当Shell程序执行到eval语句的时候,Shell读入参数args,并将它们组合成一个新的命令,然后执行。也就是重新运算求出参数的内容。eval可以读取一连串的参数,然后依据参数本身的特性来执行。参数不限数目,彼此之间用分号分开。
eval会对后面的命令进行两遍的扫描,如果第一遍扫描后,命令是普通命令,则执行此命令;如果命令中含有变量的间接引用,则保证间接引用的语义。也就是说,eval语句将会首先扫描命令行进行所有的置换,然后再进行该命令。因此,eval命令适合用于那些一次扫描无法实现其功能的变量。
eval执行分两个步骤:
第一步:执行变量的替换。
第二步:执行替换后的命令。
示例1:
[root@vm1 scripts]# cat noeval.sh
echo \$$#
[root@vm1 scripts]# sh noeval.sh arg1 arg2
$2
[root@vm1 scripts]# cat eval.sh
eval "echo \$$#"
[root@vm1 scripts]# sh eval.sh arg1 arg2
arg2
代码说明:
1)\$$# $#是特殊变量,表示传参的个数,然后前面的\$是转义,显示$。
2)没有加eval的时候,只是进行了第一步变量的替换,将传参的个数2替换了$#。然后就进行了显示。
3)加了eval语句,则进行了两次扫描,第一次,是变量的替换。然后再执行替换后的命令,显示$2的值,也就是arg2。
4)这个例子很典型。
如果我们知道参数的个数,如我们输入两个参数arg1 arg2,我们可以使用$2来查看最后一个参数arg2。
但是如果我们不知道参数个数,还想查看最后一个参数怎么办呢?我们想到$#,传给Shell脚本的个数,echo $#显示的其实是参数个数,而使用eval echo "$$#" 才显示最后一个参数。跟示例1一样。
示例2:
[root@vm1 scripts]# cat test
Hello world!
[root@vm1 scripts]# WORD="cat test"
[root@vm1 scripts]# echo $WORD
cat test
[root@vm1 scripts]# eval $WORD
Hello world!
代码说明:
1)eval命令对后面的命令进行了两次扫描,第一次将$WORD替换为cat test,第二次执行cat test。
2)这些需要进行两次扫描的变量有时也称为复杂变量。不过这些变量并不复杂。
示例3:
回显简单变量:
[root@vm1 scripts]# NAME=filename
[root@vm1 scripts]# echo $NAME
filename
[root@vm1 scripts]#
[root@vm1 scripts]# eval echo $NAME
filename
示例4:
在file文件中,有两列数据,第一列对应KEY,第二列对应VALUE,使用eval命令将KEY和VALUE的值对应起来,从文件中读取。
[root@vm1 scripts]# cat file
NAME chang
AGE 28
SEX nan
[root@vm1 scripts]# cat file1.sh
#!/bin/bash
while read KEY VALUE
do
eval "${KEY}=${VALUE}"
done < file
echo "$NAME $AGE $SEX"
[root@vm1 scripts]# sh file1.sh
chang 28 nan
需要注意的是:
1)eval不能获得函数的返回结果;
2)eval无嵌套的意义。shell中的eval将后面的eval命令简单当作命令字符串执行,失去了嵌套作用,嵌套被命令替换取代。