对 eval 命令的理解
eval
格式:eval [argument...]
可以二次迭代参数中的引用变量,然后将参数作为命令,在shell中执行
如果是多个参数,那么变量替换之后必须符合某个命令的格式,否则eval会报错“**未找到命令”
与echo的区别:
- echo 对后面参数中的引用变量只能进行一次迭代
- echo 后面的参数是作为字符串输出到命令行,而不是作为命令在shell中执行
示例:
-
一次迭代可以解析引用变量的嵌套
# 引用变量的嵌套 file="txt.txt" dir="~/testcase/$file" t="cat $dir" echo $t eval echo $t eval $t # 输出结果 # $t 解析为 cat ~/testcase/txt.txt,然后作为 echo 命令的参数,输出到终端 cat ~/testcase/txt.txt # 先将 $t 解析为 cat /home/lfp/testcase/txt.txt,再将 echo cat /home/lfp/testcase/txt.txt 作为命令, # 在shell中执行,echo 命令的作用便是将后面的参数作为字符串输出到终端 cat /home/lfp/testcase/txt.txt # 先将 $t 解析为 cat /home/lfp/testcase/txt.txt,再将 cat /home/lfp/testcase/txt.txt 作为命令,在shell中执行 test case txt file # 此为 txt.txt 文件中的内容,作为cat 命令的执行结果输出到终端
-
二次迭代可以解析,一次迭代后,和参数中的'$',组成的,新的引用变量
lfp@legion:~$ days=365 lfp@legion:~$ year=days lfp@legion:~$ echo $year days lfp@legion:~$ echo \$$year $days # 第一次 $year 解析为 days,跟参数中的 $,组合成新的引用变量 $days,变为 eval echo $days # 第二次 $days 解析为365,变为 eval echo 365,消除了引用变量,于是将 echo 365 作为命令,在shell中执行 # 替换之后的参数为 echo 365 符合echo命令格式,于是在shell中执行 echo 365 这个命令,输出 365 lfp@legion:~$ eval echo \$$year 365 # 参数 \$$year 被两次解析为365,eval 便将 365 作为命令,在shell中执行,但是365 不是一个命令,所以报错 lfp@legion:~$ eval \$$year 365:未找到命令
-
官方例子改编
# 定义两个变量 lfp@legion:~$ foo=10 x=foo # 一般命令的执行,对于引用变量只解析一次 # 下面命令的执行结果是 y=$foo lfp@legion:~$ y='$'$x # 先解析为 '$'foo,再赋值给变量 y lfp@legion:~$ echo $y $foo lfp@legion:~$ echo y='$'$x # 先解析为 y='$'foo,再作为echo命令的参数,输出到终端 y=$foo lfp@legion:~$ echo $y $foo # eval 可以两次迭代引用变量 lfp@legion:~$ eval echo y='$'$x y=10 lfp@legion:~$ echo $y # y=10 未作为命令在shell中执行,变量 y 的值未改变 $foo lfp@legion:~$ eval y='$'$x lfp@legion:~$ echo $y # y=10 作为命令在shell中执行,变量 y 的值被改变 10
-
测试3次迭代
lfp@legion:~$ a=b lfp@legion:~$ b=c lfp@legion:~$ c=d lfp@legion:~$ eval echo $a b lfp@legion:~$ eval echo '$'$a c # 自己测试没有3次迭代 lfp@legion:~$ eval echo '$''$'$a 21947b
参考
https://unix.stackexchange.com/a/23115
http://cn.linux.vbird.org/linux_basic/Mandrake9.0/0320bash.php#eval