eval--一层一层剥开我的心
如果你愿意一层一层一层的剥开我的心
你会发现你会讶异
你是我最压抑
最深处的秘密
有这样一个命令,它会一层一层剥开你的心,发现你最深处的秘密,这个命令就是eval.
上周的文章中就用到了这个命令:
eval `dircolors .dir_colors`
eval本身挺简洁,有时也蛮有用,于是总结一下。
用法:
eval CommandLine
描述:
eval对后面跟随的CommandLine进行两次扫描:第一次扫描,会进行普通的命令执行和变量替换;第二次扫描,若第一次扫描运行得到的命令或变量还可以再一次运行或替换,则再一次运行命令或进行变量替换,而对于不能再次运行或替换的部分则保留第一次的形式(语文功底实在令人汗颜)。还是举例说明吧。
eval与变量二次替换
eval的manual中有这样一个例子:
EXAMPLES
foo=10 x=foo #定义两个变量
y='$'$x #定义变量y, x=foo, 则y=$foo,但是最终的y=$foo or y=10?看后面...
echo $y #返回y的值
$foo #结果显示y=$foo
eval y='$'$x #定义相同的变量,前面加eval
echo $y #返回y的值
10 #结果显示y=10
上面的例子中,不使用eval的情况下,变量y的值为$foo,尽管$foo=10,但是shell并不会进行再一次的变量替换;而使用了eval之后,变量进行了二次替换,最后$y=10。
这就是eval的作用,另一个例子:
写一个名为script.sh的脚本,脚本的功能是输出相应的参数,内容如下:
##script.sh
echo "Name of this script: $0."
echo "First argument: $1."
echo "Second argument: $2."
echo "There are $# arguments."
echo "Last argument: \$$#."
$0为该脚本的名称,$1是传递给脚本的第一个参数;$2是传递给脚本的第二个参数;$#是传递给脚本的参数总个数,我们也可以通过\$$#拿到这个脚本最后一个参数的内容。运行一下这个脚本并传递参数a, b, c:
sh script.sh a b c
这里最后一行的输出为:
Last argument: $3.
$3并没有替换成c。
我们修改一下这个脚本的内容,在最后一行前面加eval:
##script1.sh
echo "Name of this script: $0."
echo "First argument: $1."
echo "Second argument: $2."
echo "There are $# arguments."
eval echo "Last argument: \$$#."
再次运行一下:
sh script1.sh a b c
最后一行的输出变为:
Last argument: c.
所以,通过eval,$3再次替换为c。
eval与命令执行
eval不仅可以进行变量的二次替换,还可以对替换后得到的命令进行再执行。
例子:
写一个脚本,内容如下:
##date.sh
a="date"
eval `echo $a`
执行一下看结果:
输出的是今天的日期,说明$a的值date被当作命令执行了。如果我们不加eval, 只会输出date这个字符而已。
同样,对于上周提到的命令:
eval `dircolors .dir_colors`
会先执行 dircolors .dir_colors命令,得到的内容会进行变量的替换与命令的再次执行。
假如我们把dircolors .dir_colors暂时先存到一个变量里,再eval这个变量,应该会得到相同的运行结果。
##
a=`dircolors .dir_colors`
eval $a
之前我们的文件夹颜色是洋红(di=01;35),我们改变为蓝色(di=01;34),运行一下命令果然变了过来。
这就是eval,它会将命令一层层剥开并憨厚地执行,在有些时候可以给我们带来大方便。由于没找到太好的参考资料,第二部分的内容(eval与命令执行)有一些自己的理解,未经证实,大家谨慎参考,要是哪里不对请帮忙指正,多谢啦!