eval和反引号(反撇号)之间的区别

8
有人能告诉我这里的主要区别是什么,以及为什么后者不起作用吗?
test="ls -l"

现在两者都可以正常工作:

eval $test
echo `$test`

但在这种情况下:
test="ls -l >> test.log"

eval $test
echo `$test`

后者不起作用。为什么呢?我知道eval只是执行一个脚本,而单引号则执行它并将结果作为字符串返回。是什么让在要执行的命令中使用>>或类似的东西变得不可能?也许有一种方法可以使它与单引号一起工作,我做错了些什么吗?


2
它们被称为“反引号”。 - dogbane
@dogbane,哦,那也是问题的一部分:D 谢谢,我不知道它们被称为什么。 - Kelu Thatsall
回答你的最后一个问题:是的,你做错了什么。如果你正在使用eval或将要执行的代码放在字符串中,99.9%的情况下你都做错了。你的脚本将更难理解,更难调试,并且存在安全问题:http://mywiki.wooledge.org/BashFAQ/048 - aktivb
2个回答

6
当您使用反引号来执行命令时,发送到shell的命令是:
ls -l '>>' test.log

这使得>>test.log成为ls的参数(注意>>周围的引号)。

在使用eval时,执行的命令是:

ls -l >> test.log

(通过输入“bash -vx scriptname”来执行您的脚本,以查看正在发生的情况。)

我有点从错误信息中理解了,但为什么会发生这种情况呢?有没有办法用反引号来防止它发生? - Kelu Thatsall
在第一种情况下,包括重定向符号 >> 在内的所有内容都是字符串的一部分,并被字面解释。 - devnull
2
这是否意味着反引号实际上会将它们解释的字符串用空格拆分,并将第一个元素作为命令,而后面的作为参数?你对此无能为力吗? - Kelu Thatsall
1
是的,你无法对此做任何事情。要么使用 eval 或者类似这样的东西:test="ls -l"; $(test) >> "test.log" - devnull
1
如果字符串被分割成那样,那么为什么只执行“ls -l >> test.log”时这些反引号起作用并生成文件!为什么“$something”不等于“contentOfSomething”? - JohnyTex
@JohnyTex 我认为这是因为$会扩展和分割变量,所以我们通常在$周围加上双引号。https://dev59.com/gWcs5IYBdhLWcg3wgkSu https://mywiki.wooledge.org/WordSplitting - Stan

0

eval是“表达式值”的意思。

test="ls -l >> test.log"
eval $test

在终端中执行与

相同的方式。
ls -l >> test.log

是否

echo 仅用于显示目的。


我知道那是什么,我想知道为什么同样的命令在反引号中不起作用。 - Kelu Thatsall

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接