如果我有树:
.
├── child
├── dir1
├── dir2
├── dir3
├── file1
├── file2
└── file3
这是在以下命令中发出这些命令的结果child
:这可以工作并复制所有文件和目录:
cp -r ../* .
----
cp: cannot copy a directory, '../child', into itself, './child'
这仅复制child
文件,但不复制任何目录:
cp -r .. .
----
cp: cannot copy a directory, '..', into itself, '.'
答案1
查看实际执行的命令:
$ set -x; cp -r ../* .
+ cp -r ../child ../dir1 ../dir2 ../dir3 ../file1 ../file2 ../file3 .
cp: cannot copy a directory, '../child', into itself, './child'
$ set -x; cp -r .. .
+ cp -r .. .
cp: cannot copy a directory, '..', into itself, '.'
您的两个命令都尝试将目录复制到自身中,从而导致循环。实现cp
可能会检测到它,并在某个时刻停止,或者无限期地继续复制(例如,GNU 和 BusyBoxcp
停止;FreeBSDcp
继续复制,直到达到文件名长度限制;类似地,cp
在 MacOS 上继续复制,如下所示关于 U&L 的另一个问题似乎建议)。
无论如何,递归地将目录复制到自身中最终将因错误而停止。
假设问题是关于 GNU cp
(您可能在 GNU/Linux 系统上拥有的那个),一般情况下您的第二个命令(cp -r .. .
) 将复制(不可预测的?)部分的树的根部..
,检测循环并因错误而停止,而不对该树中的任何内容进行任何进一步处理。
另一方面,在第一个命令 ( cp -r ../* .
) 中,cp
给出了八个单独的参数。虽然将child
的内容复制到child
失败,但其他目录和文件可以毫无问题地复制,因为它们都不包含child
自身。但请注意,这在不检测循环并不断进行递归复制
的系统上不会按预期“工作” 。cp
作为更安全的方法,要将父目录的所有内容复制到当前目录(child
)(不包括当前目录本身),您可以使用:
$ shopt -s nullglob dotglob extglob
$ cp -r ../!(child) .