cp -r 的語法差異以及如何克服它們
假設我們在一個空白目錄中。然後,以下命令:
mkdir dir1 cp -r dir1 dir2
產生兩個(空白)目錄
dir1
和dir2
,其中dir2
已創建為dir1
. 但是,如果我們這樣做:mkdir dir1 mkdir dir2 cp -r dir1 dir2
然後我們反而發現
dir1
現在已經被放入了裡面dir2
。這意味著完全相同的cp
命令的行為會有所不同,具體取決於目標目錄是否存在。如果是這樣,那麼該cp
命令的執行方式與此相同:mkdir dir1 mkdir dir2 cp -r dir1 dir2/.
這對我來說似乎非常違反直覺。我原以為
cp -r dir1 dir2
(當dir2
已經存在時)會刪除現有的dir2
(和任何內容)並將其替換為dir1
,因為這是cp
用於兩個文件時的行為。我知道遞歸副本本身有點不同,因為目錄在 Linux 中的存在方式(以及更廣泛地在類 Unix 系統中),但我正在尋找更多關於為什麼選擇這種行為的解釋。如果您可以向我指出一種確保cp
行為符合我預期的方法(例如,無需事先測試並刪除目標目錄),則可以加分。我嘗試了幾個cp
選項,但沒有任何運氣。我想我會接受rsync
為其他不知道該命令的人在這個問題上發生的解決方案。如果這種行為不普遍,我在 CentOS 上,使用 bash。
您正在尋找的行為是一種特殊情況:
cp -R [-H|-L|-P] [-fip] source_file... target
$$ This $$form 由兩個或多個指定了 -R 選項的操作數表示。cp 實用程序應將根在每個 source_file 的文件層次結構中的每個文件複製到名為如下的目標路徑:
- 如果目標存在並命名現有目錄,則文件層次結構中每個文件的相應目標路徑的名稱應為目標的串聯,
<slash>
如果目標不以 a 結尾,則為單個字元<slash>
,以及文件相對於文件的路徑名包含 source_file 的目錄。- 如果target不存在且指定了兩個操作數,則source_file對應的目標路徑名稱為target;文件層次結構中所有其他文件的相應目標路徑的名稱應是目標、
<slash>
字元和文件相對於 source_file 的路徑名的串聯。如果目標不存在並且指定了兩個以上的操作數,這將是一個錯誤……
因此,我會說不可能
cp
做你想做的事。由於您的預期行為是“
cp -r dir1 dir2
(當dir2
已經存在時)將刪除現有dir2
(和任何內容)並將其替換為dir1
“:rm -rf dir2 && cp -r dir1 dir2
你甚至不需要檢查是否
dir2
存在。解決方案是在源
rsync
中添加一個尾隨/
,以便它不會將dir1
自身複製到dir2
但將內容複製dir1
到dir2
(它仍會將現有文件保留在 中dir2
):$ tree dir* dir1 └── test.txt dir2 └── test2.txt 0 directories, 2 file $ rsync -a dir1/ dir2 $ tree dir* dir1 └── test.txt dir2 └── test.txt └── test2.txt 0 directories, 3 files $ rm -r dir2 $ rsync -a dir1/ dir2 $ tree dir* dir1 └── test.txt dir2 └── test.txt 0 directories, 2 files