![在管道中使用名称中包含空格的文件](https://linux22.com/image/20787/%E5%9C%A8%E7%AE%A1%E9%81%93%E4%B8%AD%E4%BD%BF%E7%94%A8%E5%90%8D%E7%A7%B0%E4%B8%AD%E5%8C%85%E5%90%AB%E7%A9%BA%E6%A0%BC%E7%9A%84%E6%96%87%E4%BB%B6.png)
我有一个名为的文件夹play
,其中包含一个文件damn file
(带空格)。当我使用find
并将输出传送到tar
:
find play/ -name 'damn*' | tar cf archive.tar -T -
它工作完美。为什么这有效 的输出find
包含应该导致问题的空间tar
。当我使用这个命令时:
tar cf archive.tar $(find play/ -name 'damn*')
bash 显示这些错误:
tar: play/damn: Cannot stat: No such file or directory
tar: file: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors
我很困惑。为什么第一个例子有效?
答案1
在第二个示例中,换行符被 shell 删除,shell 对命令替换的输出进行分词。由于默认情况下包含换行符IFS
,因此它们被视为字段分隔符,而不是字段本身的一部分。在第一个示例中,输入来自管道而不是 shell,因此 shell 无法进行分词。
双引号命令替换 ( "$(find ... )"
) 将防止发生分词,但find
内部命令替换几乎总是坏的想法所以不要这样做。为了获得最大的安全性,只要您可以访问 GNU 版本的 Unix 工具,您就应该使用空分隔符选项:
find dir/ -name '...' -print0 | tar cf foo.tar --null --no-recursion -T -