我对bash进行了一些实验,甚至在阅读了高级bash脚本编写指南的相关部分之后,我无法解释我正在观察的内容。
测试情况:名为“test”的目录,其子目录为“target”,有两个文件:“a b”和“c d”(名称包含空格)。我想将文件移动到目标目录中,然后我就会把它变得更加复杂:
cp $(echo "'a b' 'c d'") target
这给了我以下结果:
cp: Aufruf von stat für „'a“ nicht möglich: Datei oder Verzeichnis nicht gefunden
cp: Aufruf von stat für „b'“ nicht möglich: Datei oder Verzeichnis nicht gefunden
cp: Aufruf von stat für „'c“ nicht möglich: Datei oder Verzeichnis nicht gefunden
cp: Aufruf von stat für „d'“ nicht möglich: Datei oder Verzeichnis nicht gefunden
就好像有什么东西从内部echo命令的输出中删除单引号。但如果我做了:
echo $(echo "'a b' 'c d'")
结果是:
'a b' 'c d'
一些bash大师可以指点我的文档让我明白吗?这将使我周五完成!
编辑:我意识到太晚了,不会被删除而是被忽略了。这对我来说更加困惑,也需要解释。
答案 0 :(得分:5)
您的方法不起作用的原因:
cp $(echo "'a b' 'c d'") target
命令替换($(
和)
之间的位)受分词的约束。您使用双引号意味着echo
只能看到一个参数。但是,父shell将空白处echo
的输出拆分为'a b'
,'c
和d'
,即四个单独的单词。
与往常一样,使用set -x
有助于可视化这些内容:
$ cp $(echo "'a b' 'c d'") target
++ echo ''\''a b'\'' '\''c d'\''' # the subshell
+ cp ''\''a' 'b'\''' ''\''c' 'd'\''' target # the parent shell
单引号显示每个单词的边界(虽然在这种情况下,事情有点混乱,因为你也有自己的单引号......)。
如果你在命令替换周围加上双引号:
cp "$(echo "'a b' 'c d'")" target
然后不会发生分词,这意味着命令替换的结果将是一个单词,尽管这会导致一个新问题:
$ cp "$(echo "'a b' 'c d'")" target
++ echo ''\''a b'\'' '\''c d'\'''
+ cp ''\''a b'\'' '\''c d'\''' target
现在cp
期待找到一个名为'a b' 'c d'
的文件,但您没有。{/ p>
为了完整起见,复制这些文件的最佳方法是:
cp 'a b' 'c d' target
答案 1 :(得分:1)
您需要eval cp $(echo "'a b' 'c d'") target
代替cp $(echo "'a b' 'c d'") target