人们常说变量在使用时应该加双引号。
在下面的示例中,我希望将命令echo "You can't see me"
放在变量中,并以输出为 的方式运行它You can't see me
。这是最终目标。
$ cmd="echo \"You can't see me\""
$ echo "$cmd"
echo "You can't see me"
$ $cmd
"You can't see me"
$ "$cmd"
echo "You can't see me": command not found
所以$cmd
跑了,它包含了我不想有的双引号,并且遵循双引号变量的建议导致了错误。
尽管资源表明建议有例外,但该建议是否有例外总是应该使用?
eval "$cmd"
我知道如何通过运行(或不带双引号)或运行后对输出进行适当的转换(不带双引号)来获得我想要的结果$cmd
,但如何避免此问题?
答案1
人们常说……
事实是资源比如说 ...
不要盲目听从“建议”;没有办法“正确”地进行货物崇拜编程。是否有一些主要的“资源”,例如 bash(1) 联机帮助页或标准规范?
如果您想将字符串评估为脚本片段,那么您应该使用eval
.这就是它的用途:
cmd="echo \"You can't see me\""
eval "$cmd"
当您使用不带引号的变量时,不会再次扫描其扩展以查找单引号或双引号等 shell 元字符并重新解析,但只会在变量中的字符上进行拆分IFS
并进行全局扩展(如果它包含任何*
,?
或[
字符) ):
cmd="echo \"What's a *? \""
eval "$cmd"
What's a *?
$cmd
"What's a [all the files in your directory] "
在最后一个示例中,cmd
将被扩展,然后拆分为echo
、"What's
、a
和,将被全局扩展,然后 将使用所有其他字符串作为参数运行,并将它们以空格连接打印到标准输出(并且在某些 shell 中*?
),还将解释其参数中的其他转义)。"
*?
echo
echo
\n