Bash

為什麼’cp -r ../* .‘工作但不是’cp -r ..’

  • July 3, 2020

如果我有樹:

.
├── 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, '.'

查看實際執行的命令:

$ 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) .

引用自:https://unix.stackexchange.com/questions/595250