语法:eval cmdLine
eval可以读取一连串的参数,然后按照参数特性来执行。参数数目不限,彼此之间用分号隔开。 eval会对后面的cmdLine进行两遍扫描,如果在第一遍扫面后cmdLine是一个普通命令,则执行此命令;如果cmdLine中含有变量的间接引用,则保证间接引用的语义。也就是说,eval命令将会首先扫描命令行进行所有的置换,然后再执行该命令。因此,eval命令适用于那些一次扫描无法实现其功能的变量。
eval 执行以下两个步骤:
第一步,执行变量替换,类似与C语言的宏替代;
第二步,执行替换后的命令串。
下面来看几个例子:
1、执行含有带字符串的命令
我们可以新建一个文件test将字符串”HelloWorld!“写入文件中,把cat test赋值给变量WORD,如果我们echo WORD并不能的到test中的内容;然而eval WORD则能显示文件中的内容,因为eval命令对后面的命令进行了两次扫描,第一次将WORD替换为 cat test,第二次执行cat test。
这些需要进行两次扫描的变量有时被称为复杂变量。不过这些变量本身并不复杂。eval命令不仅可以回显复杂变量,也可以用于回显简单变量。
2、回显简单变量
3、eval命令还可以获取传给shell的最后一个参数
举例如下:
set 11 22 33 44
如果要输出最近一个参数,即44,可以使用如下命令,
echo $4
但是如果我们不知道是几个参数的时候,要输出最后一个参数,大家可能会想到使用$#来输出最后一个参数,
如果使用命令: echo “\$$#”则得到的结果是 4,而不是我们想要的44.这里涉及到一个变量简介引用的问题,我们的本意是输出 $4,默认情况下,命令后忽略变量简介引用的情况。
这时候,就可以使用eval命令。
eval echo “\$$#”
得到结果为44.
4、条件筛选
在file文件中写入两列数据,第一列对应KEY 、第二列为VALUE,使用eval命令将KEY与VALUE的值对应起来,从文件中读取
注意:
1、eval 不能获得函数处理结果。
2、eval 嵌套无意义,在其他语言中可以通过 eval(eval(“code”))
,来执行(执行动态生成的 code 的返回),而由于shell 中 eval 将后面的 eval命令简单当作命令字符串执行,失去了嵌套作用,嵌套被命令替换取代。
命令代换:` 或者$()
由反引号括起来的也是一条命令,shell先执行该命令,然后将输出结果立即代换到当前命令行中。
使用反引号的缺点如下:
1.它比较陈旧。
2.非常容易和单引号混淆。
3.它会对\进行跳脱处理。而$()不会。
我们知道,shell里的单引号会保持所有字符的字面值,所以引号里的执行结果应该是\ \ 。但是用反引号输出的结果却是 \ ,这就是由于它对 \ 进行了跳脱处理。
所以,一般情况下建议使用$(),这样比较直观,但是它也有它的缺点,并不是所有的类unix系统都支持这种方式,但反引号是肯定支持的。也就是说移植性不如反引号。
反引号与$()的比较:
1.
反单引号适用于任何类unix平台,他的适用性比较高。但是$符号却不是。
容易造成视觉误差。
2.在初期学习的时候反单引号
3.在多层次的复合替换中“之间需要反斜线()处理,但是$()就比较直观。 嵌套的命令替换
在多层次的复合替换中,反引号须要额外的跳脱( )处理,而 $( ) 则比较直观。例如:
cmd1`cmd2\如果有多个命令嵌套就比较复杂了。而用()就比较直观比如(cmd1(cmd2(cmd3)))
cmd1cmd2你这么写就是错的。需要