关于shell编程(5):eval用法

eval可以读取一连串的参数,然后按照参数特性来执行。 
eval会对后面的命令进行两遍扫描,如果第一遍扫描后,命令是个普通命令,则执行此命令;如果命令中含有变量的间接引用,则保证间接引用的语义。也就是说,eval命令将会首先扫描命令行进行所有的置换,然后再执行该命令。因此,eval命令适用于那些一次扫描无法实现其功能的变量。 
eval 执行以下两个步骤: 
第一步,执行变量替换,类似与C语言的宏替代; 
第二步,执行替换后的命令串。 
这里只简单介绍两种基本用法:
1、执行含有带字符串的命令 
我们可以新建一个文件leo将字符串“I am leo”!“写入文件中,把cat leo赋值给变量content,如果我们echo content并不能的到leo中的内容;然而eval content则能显示文件中的内容,因为eval命令对后面的命令进行了两次扫描,第一次将content替换为 cat leo,第二次执行cat leo。  

[xxx@xxx xxx]$ vi leo     //新建leo文件并写入字符串
[xxx@xxx xxx]$ vi eval_test.sh    //新建脚本文件并编辑
#!/bin/bash
content="cat leo"
echo $content
eval $content
[xxx@xxx xxx]$ ./eval_test.sh
cat leo
I am leo
[xxx@xxx xxx]$

这些需要进行两次扫描的变量有时被称为复杂变量。不过这些变量本身并不复杂。eval命令不仅可以回显复杂变量,也可以用于回显简单变量。 
2、回显简单变量  

#!/bin/bash
content=leoisthebest            #content存储的是普通变量,不是命令
echo $content
eval echo $content            #注意这里的echo不可以丢,否则eval执行会出错
[xxx@xxx xxx]$ ./eval_test.sh
leoisthebest
leoisthebest
[xxx@xxx xxx]$

接下来是我在实际shell编程过程中遇到的一个情况,做个记录,有兴趣的可以看一看

#!/bin/bash
Get_value()
{
    eval "echo \${$1}"    #引号内进行初次变量替换后为"echo \${val}",去掉引号等价于 echo $val
}
main()
{
val="success"
get=val        #此处并非像C中一样将val的值赋值给get,而是将“val”这个字符串赋值给get
ret=`Get_value $get`    
}
main $*        #调用main

[xxx@xxx xxx]$ ./eval_test.sh
success
[xxx@xxx xxx]$

调用‘Get_value’函数的时候,参数是get的值即字符串‘val’,在函数体内部,代码

eval "echo \${$1}"      #$1为函数的第一个参数,此处即val

转换为

eval "echo \${val}"

由于引号包含所以加了转义符'\',去掉引号变为

eval echo $val

接下来就不难理解了,最后ret接收到的值就相当于执行“echo $val”的结果,此处结果为success。

如果get变量存储的是一个普通字符串,当eval执行到 “echo $val”时,由于val没有意义,则会打印出空值,当val本身也有值时,才能成功替换并打印。

猜你喜欢

转载自blog.csdn.net/Leo_csdn_/article/details/81559737
今日推荐