UNIX mvプログラムがディレクトリに-R(再帰)オプションを必要としないのに、cpはそれを必要とするのはなぜですか?


58

使用する必要があるとき、cpまたはmv-Rdirで作業するときにオプションが必要ですか?」GNUでは、coreutils cpは必要であり-R、必要ありmvません。

dirsをコピーcpするための-Rオプションが必要であり、必要ない理由を見つけることができmvません。cpダイアリングなしで-R(ただし、再帰的な動作をすることで)ツールを使用することで誰かの習慣を壊すこと以外は問題を引き起こさない-Rと思いmvます。

説明を知っていますか?ずっと前に理由があったのでしょうか?


追加の質問:なぜcoreutils開発者はcpデフォルトでコピーディレクトリを再帰的に作成しないのですか?

回答:


45

ディレクトリは、(概念的に)名前のリストと、それらの名前が指すiノード番号を含む特別な「ファイル」です。一部の名前はサブディレクトリにすることができます。..親ディレクトリを指す特別なエントリがあります。

したがって、ファイルの名前を明確に変更するのは簡単です。ディレクトリエントリの名前を変更するだけで、それ以外は何も変更しません。これは、ファイルが実際にファイルであるか、別のディレクトリのコンテンツを保存するために使用される「ファイル」であるかを保持します。実際、同じrenamesyscallが両方を実行します。

ただし、コピーはそれほど簡単ではありません。あなたは可能性があり、単にディレクトリ「ファイル」をコピーしたが、その後、あなたは、ファイルが(彼らはハードリンクだろう)は同じである2つのディレクトリを持っていると思います。ディレクトリへのハードリンクを許可するシステムがあれば、それらは許可されますが、少なくとも非ルートに対しては許可されていないため、各サブディレクトリに対してそのコピーを実行する必要があります。あなたが実際に頼むことができるcpと、この動作のためにcp -lR-lハードリンクのために、-Rその再帰のために。

しかし、すべてをリンクしたままにすることは、おそらくあなたが望むものではありません。代わりに、cp各ファイルをコピーします。これはかなり高価な操作です。各ファイルはメモリに読み込まれ、2番目の場所のディスクに書き戻される必要があります。実際には、ファイルを開いたり、読み込んだり、書き込んだり、閉じたりするために、いくつかのsyscallが必要です。これは、各ファイルに対して繰り返す必要があります。

従来のファイルシステムもディスク上でこのように機能します。個々のファイルを個別に調べてコピーする以外に、大量のファイルをコピーする方法はありません。これらは、基本的なコマンドラインユーティリティが設計されたときに使用されていたファイルシステムのタイプです。


あるmvファイルシステムから別のファイルシステムに同じ「ディレクトリエントリの名前を変更するだけ」ですか?
rslnx

5
いいえ、クロスファイルシステムはコピー+削除と同じです(実際、renameクロスファイルシステムではsyscallは失敗します)。歴史的に、mvfs間移動もサポートされているかどうかはわかりません。
デロバート

9
憶測ではなく直接的な経験から、クラシカルmvはデバイス間の移動をサポートしていなかったと言えます。以前はrename()失敗した場合にエラーメッセージを表示して印刷するだけでした。誤ってこの新機能を初めて使用したときのショックを受けた気持ちを今でも覚えています。なぜこのmvに時間がかかるのですか?ああ、それは私が意図しなかった再帰的なコピーをしている!
アランカレー

5
@RuslanKhusnullin一般的なコマンドのコマンドラインオプションは、シェルスクリプトで使用されるため、変更が非常に困難です。誰かが、cpの現在のrefuse-to-copy-dirs動作に依存している可能性があります。cross-fsのものはおそらく破損を引き起こす可能性が低いと判断されましたが、ご覧のとおり、アランはまだ驚いていました。
derobert

1
@derobert、それはしませんでした(クロスファイルシステムmvはVAX上のBSD 4.2の個々のファイルに対してのみ機能しました)。
フォンブランド

21

別の質問をすることから始めましょう。

違いは何であるcpとはcp -R

-Rフラグがなければ、ファイルをコピーすることしかできません。誰かがディレクトリを非再帰的にコピーしたいというのはかなり珍しいからです。構造。それはめったに人々が望むものではなく、実際にこれを行う別のプログラム(ln)があるため、ディレクトリの非再帰的コピーは許可されていません。

次に何が違いかもしれないmvmv -R

mv a bディレクトリ内の1つのエントリの名前を変更するだけなので、ディレクトリがmv編集されると、その内容も自動的に移動されます。その意味で、mvすでに再帰プロパティ、つまり、名前が変更されたディレクトリ内のすべてのエントリの「名前変更」、たとえばfrom a/1を提供していb/1ます。mvすなわち、ディレクトリ名前が変更されたことをしないようaにしbますが、続けa/1a/1、彼らは何かを移動を参照するとき、人々が理解できません:あなたは食器棚を移動するときは、食器棚の内容も同様に移動されます。内容なしでディレクトリを移動する他の操作も既に利用可能ですmkdir


2
それは私がちょうど考えていた、右だcpmv「コピーを作成」と「移動」:それらが命名されていることを事業として。したがって、コーヒーカップのコピーを作成する場合は、同じ詰め物(コーヒードリンク)のコーヒーカップをもう1つ用意する必要があります。問題は、ツールが「通常の人々」向けではなく、ファイルやファイルのような仮想エンティティではなく、ディスクおよびファイルシステムの構造を認識しているオタク向けであることです。
rslnx

1
適切に構成された、合理的な対応。
-Spedge

1
あなたのコーヒーのアナロジーがために働く@RuslanKhusnullin cpmvあまりにも-それは、理解することだけで、基本的な常識を「nerdness」のいずれかのレベルを必要としません。コーヒーカップの真のコピーは空のカップではありません。カップだけでなく、その中身(コーヒー)もすべて再帰的にコピーする必要があります。ただし、コーヒーカップを移動する場合は、内容物を個別に移動する必要はありません-内容物は容器とともに自然に移動します。
jw013

1
@ jw013「コーヒーを移動するとき、中身を別に移動する必要がない」と感心しました。本当に理にかなっています、ありがとう。しかし、それは抽象化の別のレイヤーです。メタ情報のないバイトシーケンスのようなファイルを考える一方で、「ファイルをiノードとして扱う」ことを意味すると思います。
rslnx

6

通常、Unixのロジックに戸惑うとき、私はPlan9を見て、Unixの発明者が何年も後に下位互換性にこだわらず同じタスクをどのように実装したかを調べます。

そのため、Plan9はファイルのみで動作するツールcpmvツールを提供しています。

`cp f1 f2` creates f2 and copies f1's contents into it.
`mv f1 f2` renames f1 to f2 if f1 and f2 are in the same dir
           does `cp f1 f2 && rm f1` else
           can rename dirs (`mv d1 d2`) but will not move dir to another dir.

dirをコピーするためにdircp実際にあります@{cd fromdir && tar c .} | @{cd todir && tar xT}(rcシェル構文)

ディレクトリを移動するには、 dircp d1 d2 && rm -r d1

私はこの決定を制限すると考えるcpmv、ファイル操作のみ(ないのdirs)は、ディスク操作により鮮明をもたらし、使用するためのtarファイルツリーをコピーすることは理解とスクリプトのための非常に快適です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.