木がある場合:
.
├── 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やBusyBoxの停止cp
、FreeBSDはcp
ファイル名の長さ制限に達するまでコピーを続けます。同様に、cp
MacOSでもコピーは次のように続きます。U&Lについての他の質問提案されているようです)。
それにもかかわらず、ディレクトリを自分に再帰的にコピーすると、最終的にエラーが発生したときに停止します。
質問がGNU cp
(GNU / Linuxシステム上のもの)に関するものであると仮定すると、通常2番目のコマンド(cp -r .. .
)がコピーされます。(予測できない?)部分ツリーのルートで..
ループを検出し、ツリー内のどのアイテムもさらに処理せずにエラーで停止します。
一方、最初のコマンド(cp -r ../* .
)にはcp
8つの個別の引数があります。child
の内容のコピーに失敗すると、child
他のディレクトリやファイルにはchild
自分自身が含まれていないため、問題なくコピーされます。しかし、これは
ループを検出せず、継続的に再帰コピーを作成するシステムでは期待どおりに「動作」しません。cp
より安全な方法で親ディレクトリのすべての内容を現在のディレクトリ(child
)にコピーするには(現在のディレクトリ自体を除く)、次のようにします。
$ shopt -s nullglob dotglob extglob
$ cp -r ../!(child) .