操作の順序はありますかrm
? 大きなディレクトリに対して実行しましたがrm
、何が削除されたかを確認するにはどこを確認すればよいか知りたいです。 はrm
最初にファイルに対して実行され、次にディレクトリに対して実行されるのですか? それとも、inode テーブル内の何らかの情報に基づいて実行されるのですか?
仕様: GNU coreutils 8.22 の rm システム: beagleboneblack ファイルシステム上で実行されている Arch Linux は、USB 2.0 を使用する外付け Seagate HDD (ext4) で動作していました。
背景:
ディレクトリのクリーンアップを実行していたところ、
cp -r A/ B/ C/ Dest/
無意識のうちに、私はこう続けた。
rm -r A/ B/ C/ Dest/
単にパフォーマンスするつもりだったのに
rm -r A/ B/ C/
私はこれに気付き、すぐにCtrl+を押しました。具体的には、 &コマンドと組み合わせて使用していたため、3秒未満でした。存在しないだろうと予想して調べましたが、なんと、それは完全でCtime
rm
cp
Dest/
現れた影響を受けないはずです。サイズA/
B/
C/
が非常に小さいので、これは少し意外です。合計で 100~200 MB かもしれません。Dest/
ただし、1 TB にはわずかに足りません。Dest ls
/ でを実行すると、アルファベットの両端にファイルとディレクトリの両方があることがわかりました (例: AFile.txt
.... .... Zoo.txt
)。
幸運にも、rm
Dest/ ディレクトリに大混乱が生じる前に をキャンセルできましたか?rm
本当にそんなに遅いのでしょうか (ありがたいことに!)?
そうでない場合、rm
失われた可能性があるものを推測できるように、再帰的に削除するにはどうすればよいでしょうか?
失ったものを取り戻せるとは思っていません。ただ、何が吹き飛ばされたのか知りたいだけです。
答え1
rm -r
は、各引数を順番に処理します。引数がディレクトリの場合、そのディレクトリをリストします(opendir
そしてreaddir
関数または同等のメソッドを使用して、各エントリを順番に操作します。エントリがディレクトリの場合は、そのエントリを再帰的に探索します。
これは、他のアプリケーションがディレクトリを再帰的にトラバースするために使用する方法とまったく同じです ( find
、ls -Rf
など)。
トラバーサルの順序は予測できません。ほとんどのファイルシステムでは、ディレクトリ内でファイルが追加、削除、または名前変更されない限り、順序は再現可能です (順序は理論上は完全にランダムで毎回変わる可能性がありますが、そのようなファイルシステムは考えられません)。いくつかのファイルシステムでは、順序は一般にファイル名から、またはファイルが作成された順序から、あるいはその両方から推測できますが、ファイルシステムの詳細を知る必要があり、ドライバのバージョンによって異なる可能性があります。トラバーサルの順序は信頼できるものではありません。
ls
または はecho *
ファイルを名前の辞書式順序でソートします。find
および はls -f
ソートしないことに注意してください。
唯一信頼できるのは、引数が順番に処理されるということです。したがって、C/
が部分的に残っている場合は、 はDest/
変更されていないことを意味します。C/
がなくなった場合は、Dest/
ディレクトリの変更時刻を確認し、削除された時刻またはコピーが終了した時刻と比較することで、でファイルが削除された場所を把握できます。 の最初のエントリがたまたまディレクトリであったかどうかに応じて、削除される最初のファイルは、 の直接のファイルまたは階層の深いところにあるC/
ファイルである可能性があります。Dest/
Dest/
rm
の速度は、rm
削除するファイルの数に大きく左右されます。削除時間に顕著な影響を与えるには、非常に大きなファイルが必要です。作業の大部分は、各ディレクトリ エントリを順番に削除することです。ファイルのデータは消去されません。ファイルの内容を消去するには、使用されていたブロックを空きとしてマークするだけで済みます。これは比較的高速です。
答え2
Gilles が言うように、ディレクトリ内の削除の順序を一般に予測することはできませんが、最上位のディレクトリはコマンド ラインの順序で処理されることだけはわかります。
ただし、Unix ではディレクトリが空の場合のみ削除が許可されるため、ディレクトリ階層は下から上に向かって削除されることも保証されます。したがって、ディレクトリを削除するには、まずその中のすべてを削除する必要があります。サブディレクトリが含まれている場合は、まずその内容を削除する必要があり、以下同様です。