以下脚本:
$ cat runme01.sh
#!/bin/bash
A=myval
B=$A/{fix}
C=$A/fix
set -xT
echo $B
echo $C
如果运行,则打印以下内容:
$ ./runme01.sh
+ echo 'myval/{fix}'
myval/{fix}
+ echo myval/fix
myval/fix
如您所见,变量用单引号B
传递echo
,而变量C
不带它们传递。
可能是花括号导致了这种情况。
我想总是通过不带引号的方式传递它们。怎么做?
切勿尝试将跟踪输出解释为纯粹信息以外的任何内容。这是调试输出。
它在单引号中显示大括号这一事实并不意味着外壳将特定字符串解释为
myval/{fix}
其他任何内容。特别是,这并不意味着字符串被引用了! shell 在跟踪输出中添加单引号,因为大括号有时是特殊的,但是在这种情况下它们不是(因为您从不使用实际的大括号扩展)。这里也会发生同样的情况(在空目录中运行):
我的命令中没有引用
*
,所以 shell 会尝试扩展它。它不会扩展到任何东西,因此它保持未扩展。生成跟踪输出的代码注意到*
字符串中有 a 并将其引用。这是基于跟踪打印的字符串中存在的字符的机械添加单引号,它不会以任何方式影响命令或其结果。为了再次说明这一点:
即,字符串中的某些字符将导致生成跟踪输出的代码在
bash
. shell 还转义字符串中的单引号。将此与
dash
or进行比较pdksh
:这些特定的 shell 不添加引号(或转义单引号)。真的没关系,只是调试输出而已。
始终双引号变量扩展,除非您明确希望 shell 对字符串执行分词和文件名生成(通配符)。
双引号并不总是需要,但记住总是双引号比记住不需要的上下文更容易。
您的脚本,更正:
这将确保您始终获取值
$B
并$C
打印到标准输出,而不管它们的值如何。在您的原始代码中,如果$A
was*
、 using$B
和$C
unquoted 可能会引入一些匹配的文件名。请注意,跟踪输出仍将
myval/{fix}
使用此代码对字符串进行引用。别担心,它没有任何意义,它只是试图帮助调试输出的 shell。有关的: