Linux eval命令——关于空格那些事

eval命令简介

eval 属 Shell 内建命令,通过连接参数构造命令。其使用空格分隔每个参数,构造的命令应由 Shell 读取和执行。

eval 会对后面的命令进行两遍扫描。如果第一遍扫描后,命令是个普通命令,则执行此命令;如果命令中含有变量的间接引用,则保证间接引用的语义。也就是说,eval 命令将会首先扫描命令行进行所有的置换,然后再执行该命令。

命令格式:

eval [argument...]

使用示例

# eval $(cat cmd.txt)

以上命令读取文本文档cmd.txt中的内容,并将内容作为命令行来执行。

例如cmd.txt的内容如下:

# cat cmd.txt

echo “Hello World!”

执行结果为:

# eval $(cat cmd.txt)

Hello World!

非常直观。

关空格什么事?

在一项业务需求中,我会将若干文件移动命令写入文本,然后提交eval执行,例如:

# cat cmd.txt

mv “a.jpg” “a_1.jpg” && mv “b.jpg” “b_1.jpg”

相当长的时间内,该业务运行正常。直至今日,命令无法执行成功,提示:文件不存在!

经检查,文件明明就在那里。

调试后发现,原来是空格惹的祸。从上面的示例可以看到,我已经提前考虑到了文件名包含空格的情况,对文件名使用双引号包围,以避免文件名被分割为多个选项或参数。因此,该业务能够在文件名包含空格的情况下正常运行,但仅限于文件名中不存在连续空格的情况,一旦文件名中存在连续空格,则命令无法执行成功。

# cat cmd.txt

mv “a    c.jpg” “a    c_1.jpg” && mv “b.jpg” “b_1.jpg”

对于以上命令,将无法执行成功,提示找不到文件:a c.jpg。

在文件名中的连续空格较多的情况下,容易找到问题所在,当连续空格仅有两个时,需要非常仔细地观察才能发现问题。

如何解决空格问题?

经过测试后发现,eval命令的解析其参数内容,比如cmd.txt文件中的内容时,会将字符串中的连续空格合并为单一空格,即使字符串使用了双引号来包围,例如:

# cat cmd.txt

echo “Hello     World!”

执行结果为:

# eval $(cat cmd.txt)

Hello World!

因此,请慎用eval。对于本例,替代方案很简单,直接调用bash执行文本文件即可:

# /bin/bash cmd.txt

Hello     World!

猜你喜欢

转载自blog.csdn.net/Dancen/article/details/127912325