web-dev-qa-db-ja.com

cp --no-target-directoryの説明

質問:cp --no-target-directoryの使い方の簡単な例が必要です。

私はcp --no-target-directoryを理解するのにいくつかの困難を経験しています。 mv --no-target-directoryの説明 はわかりますが、cpに使用する方法を想像することはできません。

たとえば、コマンドmv /tmp/source /tmp/destが成功した場合、/tmp/source/tmp/destに名前が変更された保証はありません。他のプロセスが作成された場合、代わりに/tmp/dest/sourceに名前が変更された可能性があります。 /tmp/destをディレクトリとして。ただし、mv -T /tmp/source /tmp/destが成功した場合、/tmp/source was renamed to/tmp/dest`は問題ありません。 ( ソース

10
erch

デフォルトでは、cpは最後の引数が既存のディレクトリかどうかをテストします。これが発生した場合、cpは、ソースのベース名を使用して、そのディレクトリ内にリンクを作成します。つまり、コマンド

cp foo/bar wibble

wibbleが既存のディレクトリの場合、cpはソースをwibble/barにコピーします。 wibbleが存在しない場合、cpはソースをwibbleにリンクします。

コピーが常にwibbleであることを確認したい場合は、--no-target-directory(エイリアス-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では、ターゲットが既存のディレクトリの場合、コマンドがエラーを返すことです。これは、ディレクトリが存在しないことが予想される場合に役立ちます。予期しないことが発生する代わりに、エラーメッセージが表示されます。

同じことがmvlnにも当てはまります。ターゲットが-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'

次はどうですか?

$ 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/を記述するための別の方法にすぎません。ただし、単純なcp *では見逃されるDir_1のルートにある隠しファイルをキャッチします。

$ 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’
2
Railgun2