最近,当我阅读一个 QA时,它有一些令我意想不到的行为:
~/findtest % echo three > file\ with\ \"double\ quotes\"
~ % find findtest -type f -exec sh -c 'set -x;cat "{}"' \;
+ cat 'findtest/file with double' quotes
cat: findtest/file with double: No such file or directory
cat: quotes: No such file or directory
在我看来,当进行替换时,'cat findtest/file\ with\ \"double\ quotes\"'
只要替换上面的文件名就可以了file\ with\ \"double\ quotes\"
。如果我们保留引号包装器,它将显示:
$ cat "findtest/file\ with\ \"double\ quotes\""
cat: 'findtest/file\ with\ "double\ quotes"': No such file or directory
问:
该替换实际上做了什么导致上述有点奇怪的行为,其中 2 个子字符串“findtest/file with double”和“quotes”,而不是“findtest/file with”和“double quotes”作为"
分隔符?
您所看到的行为不是 处理“特殊字符”的结果
find
(引号对 来说不是特殊的find
),而是 的结果sh
。文件的名称是file with "double quotes"
;反斜杠是用于 shell 的转义符,它们不会出现在文件系统中,并且find
不知道它们。因此
按预期工作:
find
找到,并使用该参数findtest/file with "double quotes"
构造的调用;打开它,一切正常。cat
cat
现在,当你加入
sh
混合物时,find
效果完全相同:find
使用后跟的sh
参数构建一个的调用。处理引号,得到使用参数和的调用:-c
set -x; cat "findtest/file with "double quotes""
sh
cat
findtest/file with double
quotes
引号对分隔
findtest/file with
(带有尾随空格)和空字符串。由于第二个双引号和之间没有空格,因此它们在同一个参数中连接在一起;和double
之间的空格不会出现在引号对中,因此它会分隔单词。因此,在删除引号和拆分单词后,命令行组件是double
quotes
cat
findtest/file with double
quotes