转载于https://blog.csdn.net/baidu_37964071/article/details/80930704
在bash中,$( )与` `(反引号)都是用来作命令替换的。
命令替换与变量替换差不多,都是用来重组命令行的,先完成引号里的命令行,然后将其结果替换出来,再重组成新的命令行。
eg:
$( )与``
在操作上,这两者都是达到相应的效果,但是建议使用$( ),理由如下:
- ``很容易与”搞混乱,尤其对初学者来说。
- 在多层次的复合替换中,``必须要额外的转义字符处理(反斜线),而$( )比较直观。
- 最后,$( )的弊端是,并不是所有的类unix系统都支持这种方式,但反引号是肯定支持的。
eval命令
eval可以读取一连串的参数,然后按照参数特性来执行。参数数目不限,彼此之间用分号隔开。
eval会对后面的命令进行两遍扫描
如果第一遍扫描后,命令是个普通命令,则执行此命令;如果命令中含有变量的间接引用,则保证间接引用的语义。也就是说,eval命令将会首先扫描命令行进行所有的置换,然后再执行该命令。
因此,eval命令适用于那些一次扫描无法实现其功能的变量。
eval 执行以下两个步骤:
第一步,执行变量替换,类似与C语言的宏替代;
第二步,执行替换后的命令串。
下面来看几个例子:
例:执行含有带字符串的命令
[root@localhost ~]# cat test
Hello World!
[root@localhost ~]# WORD="cat test"
[root@localhost ~]# echo $WORD
cat test
[root@localhost ~]# eval $WORD
Hello World!
看上面的例子,把cat test赋值给变量WORD。当我们执行echo WORD就是将变量WORD的值列出来,并不能得到test中的内容;然而eval WORD则能显示文件中的内容,因为eval命令对后面的命令进行了两次扫描,第一次将WORD替换为 cat test,第二次执行cat test。
这些需要进行两次扫描的变量有时被称为复杂变量。
eval命令不仅可以回显复杂变量,也可以用于回显简单变量。
例:回显简单变量
[root@localhost ~]# NAME=filename
[root@localhost ~]# echo $NAME
filename
[root@localhost ~]# eval echo $NAME
filename
例:获取传给shell的最后一个参数
之前我们已经了解过shell语法,知道最后一个参数是$#,看如下代码,用eval可得到其内容。
[root@localhost ~]# cat test.sh
#!/bin/bash
echo "\$$#"
eval echo "\$$#"
[root@localhost ~]# chmod u+x test.sh
[root@localhost ~]# ./test.sh first last
$2
last
-
例:条件筛选
在file文件中写入两列数据,第一列对应KEY 、第二列为VALUE,使用eval命令将KEY与VALUE的值对应起来,从文件中读取:[root@localhost ~]# cat file NAME ZHANG AGE 20 SEX NV [root@localhost ~]# cat test.sh #!/bin/bash while read KEY VALUE do eval "${KEY}=${VALUE}" done < file echo "$NAME $AGE $SEX" [root@localhost ~]# ./test.sh ZHANG 20 NV
-
注意:
1、eval 不能获得函数处理结果。
2、shell中eval 嵌套无意义,在其他语言中可以通过 eval(eval(“code”)) ,来执行动态生成的 code 的返回,而由于shell 中 eval 将后面的 eval 命令简单当作命令字符串执行,失去了嵌套作用,嵌套被命令替换取代。
-