查看原文
其他

eval--一层一层剥开我的心

2017-05-16 阿现 生信媛

如果你愿意一层一层一层的剥开我的心

你会发现你会讶异

你是我最压抑

最深处的秘密


有这样一个命令,它会一层一层剥开你的心,发现你最深处的秘密,这个命令就是eval.

上周的文章中就用到了这个命令:

eval `dircolors .dir_colors`

eval本身挺简洁,有时也蛮有用,于是总结一下。

用法:

eval CommandLine

描述:

eval对后面跟随的CommandLine进行两次扫描:第一次扫描,会进行普通的命令执行和变量替换;第二次扫描,若第一次扫描运行得到的命令或变量还可以再一次运行或替换,则再一次运行命令或进行变量替换,而对于不能再次运行或替换的部分则保留第一次的形式(语文功底实在令人汗颜)。还是举例说明吧。


eval与变量二次替换

evalmanual中有这样一个例子:

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与命令执行)有一些自己的理解,未经证实,大家谨慎参考,要是哪里不对请帮忙指正,多谢啦!


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存