
問題:我需要一個簡單的例子來說明如何使用cp --no-target-directory
.
我確實在理解上遇到了一些困難cp --no-target-directory
。我明白的解釋mv --no-target-directory
,但我真的無法想像如何使用它cp
。
例如,當命令
mv /tmp/source /tmp/dest
成功時,不能保證被/tmp/source
重新命名為:如果將其他進程建立為目錄,則/tmp/dest
它可能已重新命名為。但是,如果成功,那麼/tmp/dest`就毫無疑問了。 (/tmp/dest/source
/tmp/dest
mv -T /tmp/source /tmp/dest
/tmp/source was renamed to
來源)
答案1
預設情況下,cp
測試其最後一個參數是否為現有目錄。如果發生這種情況,則cp
在該目錄內建立一個帶有來源的基本名稱的連結。也就是說,給定命令
cp foo/bar wibble
如果wibble
是現有目錄則將cp
來源複製到wibble/bar
.如果wibble
不存在則將cp
來源連結到wibble
。
如果您想確保副本始終為wibble
,則可以指定--no-target-directory
(alias -T
) 選項。這樣,如果cp
成功,您可以確定該副本被呼叫wibble
。如果wibble
已經作為目錄存在,則將cp
失敗。
以表格形式:
The target is … Without -T With -T
existing directory copy in the directory error
existing file (not dir) overwrite overwrite
does not exist create create
唯一的區別是-T
,如果目標是現有目錄,則該命令將傳回錯誤。當您期望目錄不存在時,這非常有用:您會收到一條錯誤訊息,而不是發生意外的情況。
這同樣適用於mv
和ln
。如果目標是現有目錄,則-T
它們會發出錯誤訊號,而不是默默地執行不同的操作。
對於cp
,有一種不同的情況。如果執行遞歸複製且來源是目錄,則將cp -T
來源的內容複製到目標,而不是複製來源本身。也就是說,給定
$ tree source destination
source
└── foo
destination
└── bar
然後
$ cp -rv source destination
`source' -> `destination/source'
`source/foo' -> `destination/source/foo'
然而
% cp -rvT source destination
`source/foo' -> `destination/foo'
答案2
--no-target-directory
如果您不想複製來源目錄,則可以使用下現有的目標目錄,您想要複製來源目錄到目標目錄。
以下是包含和不包含 的目錄副本的範例--no-target-directory
:
$ mkdir a
$ touch a/b a/c
$ find
.
./a
./a/c
./a/b
$ cp -r a b # b does not exist; becomes copy of a
$ find
.
./b
./b/b
./b/c
./a
./a/c
./a/b
$ rm -r b
$ mkdir b
$ cp -r a b # b already exists; a is copied *underneath* it
$ find
.
./b
./b/a
./b/a/b
./b/a/c
./a
./a/c
./a/b
$ rm -r b
$ mkdir b
$ cp -r --no-target-directory a b # b already exists; becomes copy of a
$ find
.
./b
./b/b
./b/c
./a
./a/c
./a/b
您可以透過在來源目錄名稱後面加上斜線點來實現相同的效果,/.
如下所示:cp -r a/. b
複製來源目錄a
到 b
並不是下 b
。
上述兩種方法都與「僅將來源目錄的內容複製到現有目標目錄」不同,因為如果您要求保留時間和權限,現有目標目錄將取得來源目錄的時間和權限。一個例子(編輯以刪除不必要的資訊):
$ find . -ls
drwx------ Oct 13 13:31 ./b # note date and permissions
drwxr-xr-x Jan 1 2013 ./a # note date and permissions
-rw-r--r-- Oct 13 13:23 ./a/c
-rw-r--r-- Oct 13 13:23 ./a/b
$ cp -rp --no-target-directory a b # preserve mode and timestamps
$ find . -ls
drwxr-xr-x Jan 1 2013 ./b # note copied date and permissions
-rw-r--r-- Oct 13 13:23 ./b/b
-rw-r--r-- Oct 13 13:23 ./b/c
drwxr-xr-x Jan 1 2013 ./a
-rw-r--r-- Oct 13 13:23 ./a/c
-rw-r--r-- Oct 13 13:23 ./a/b
僅內容副本不會將來源目錄的模式或時間戳傳送到目標目錄。
答案3
下面的怎麼樣?
$ cp -rvT Dir_1 Dir_2
‘Dir_1/File_3.txt’ -> ‘Dir_2/File_3.txt’
‘Dir_1/File_1.txt’ -> ‘Dir_2/File_1.txt’
‘Dir_1/File_2.txt’ -> ‘Dir_2/File_2.txt’
$ cp -rv Dir_1 Dir_2
‘Dir_1’ -> ‘Dir_2/Dir_1’
‘Dir_1/File_3.txt’ -> ‘Dir_2/Dir_1/File_3.txt’
‘Dir_1/File_1.txt’ -> ‘Dir_2/Dir_1/File_1.txt’
‘Dir_1/File_2.txt’ -> ‘Dir_2/Dir_1/File_2.txt’
因此,這只是一種不同的寫作方式cp Dir_1/* Dir_2/
。但是,它確實捕獲了 Dir_1 根目錄下的隱藏文件,而簡單的cp *
.
$ touch Dir_1/.Hidden_File_{1,2,3}.txt
$ cp -rv Dir_1/* Dir_2
cp: No match.
$ cp -rvT Dir_1 Dir_2
‘Dir_1/.Hidden_File_2.txt’ -> ‘Dir_2/.Hidden_File_2.txt’
‘Dir_1/.Hidden_File_3.txt’ -> ‘Dir_2/.Hidden_File_3.txt’
‘Dir_1/.Hidden_File_1.txt’ -> ‘Dir_2/.Hidden_File_1.txt’