是时候解决这个困扰我多年的难题了……
我不时遇到这个,并认为这是要走的路:
$(comm "$(arg)")
并认为我的观点得到了经验的强烈支持。但我不再那么确定了。Shellcheck也拿不定主意。两者都是:
"$(dirname $0)"/stop.bash
^-- SC2086: Double quote to prevent globbing and word splitting.
和:
$(dirname "$0")/stop.bash
^-- SC2046: Quote this to prevent word splitting.
背后的逻辑是什么?
(顺便说一句,这是 Shellcheck 版本 0.4.4。)
你需要使用
"$(somecmd "$file")"
.如果没有引号,带有空格的路径将在 的参数中被拆分
somecmd
,并且它将指向错误的文件。所以你需要在里面引用。的输出中的任何空格
somecmd
也会导致拆分,因此您需要在整个命令替换的外部加上引号。命令替换中的引号对其外部的引号没有影响。Bash 自己的参考手册对此并不太清楚,但BashGuide 明确提到了这一点。POSIX 中的文本也需要它,因为其中允许“任何有效的 shell 脚本”
$(...)
:例子:
一个。没有引号,
dirname
同时处理./space
和here/foo
:湾。里面的引号,
dirname
processes./space here/foo
,giving./space here
,分为两部分:C。引号外,
dirname
同时处理./space
和here/foo
,在不同的行上输出,但现在这两行形成一个参数:d。内外引用,这给出了正确答案:
(如果
dirname
只处理第一个参数,这可能会更简单,但这不会显示案例 a 和 c 之间的区别。)请注意,对于
dirname
(可能还有其他人),您还需要添加--
, 以防止文件名被用作选项,以防它碰巧以破折号开头,所以使用"$(dirname -- "$file")"
.