web-dev-qa-db-ja.com

rm -rはどのように再帰的に削除しますか?どんな順番で?

rmへの操作の順序はありますか?私は大きなディレクトリでrmを実行しましたが、何が削除された可能性があるかを確認する必要がある場所に興味があります。 rmは最初にファイルを処理し、次にディレクトリを処理しますか?それとも、iノードテーブルの情報に基づいていますか?

仕様:rm from GNU coreutils 8.22システム:動作している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+C やがて過ぎ去った。具体的には、timeコマンドをrmcpと組み合わせて使用​​していたため、3秒未満でした。私は入り、Dest/が存在しないことを期待して調べましたが、それは全体であり、影響を受けないように出現でした。 A/B/C/は非常に小さいため、これは少し意外です。合計で100〜200 MBになる可能性があります。 Dest/は1 TBに恥じています。 Dest /でlsを実行すると、アルファベットの両端にファイルとディレクトリの両方があることがわかりました(例:AFile.txt .... .... Zoo.txt)。

Dest /ディレクトリが大混乱する前に、rmをラッキーにしてキャンセルしましたか? rmは本当に遅いのですか(ありがたいことに!)

そうでない場合、何が失われたのかを推測できるように、rmはどのように再帰的に削除しますか?

失ったものを回復することを本当に期待しているのではなく、吹き飛ばされた可能性があるものに興味があるだけです。

30
N Klosterman

_rm -r_は、各引数を順番に処理します。引数がディレクトリの場合、それはディレクトリをリストし( opendir および readdir 関数または同等のメソッドを使用)、各エントリを順番に操作します。エントリがディレクトリの場合、そのエントリを再帰的に探索します。

これは、他のアプリケーションがディレクトリを再帰的にトラバースするために使用する方法とまったく同じです— find、_ls -Rf_など。

走査の順序は予測できません。ほとんどのファイルシステムでは、ディレクトリでファイルが追加、削除、または名前変更されない限り、順序は再現可能です(理論的には順序は完全にランダムで、毎回変わる可能性がありますが、それが発生するファイルシステムは考えられません)。いくつかのファイルシステムでは、一般にファイル名から、またはファイルが作成された順序から、またはその両方の組み合わせから、順序を推定できますが、ファイルシステムの詳細を知る必要があります。ドライバのバージョン。トラバーサルの順序は、信頼できるものではありません。

lsまたは_echo *_は、ファイルを名前の辞書式順序でソートすることに注意してください。 findおよび_ls -f_はソートされません。

信頼できる1つのことは、引数が順番に処理されることです。したがって、_C/_がまだ部分的に存在する場合、_Dest/_は変更されていないことになります。 _C/_がなくなった場合、ディレクトリの変更時刻を確認し、それらを_Dest/_が削除された時刻またはコピーされた時刻と比較することにより、_C/_でファイルが削除された場所を知ることができます終了しました。削除される最初のファイルは、_Dest/_内の直接のファイル、または_Dest/_内の最初のエントリがrmがたまたまトラバースしたかどうかに応じて、階層の深い場所にある可能性があります。

rmの速度は、ほとんどの場合、削除するファイルの数の問題です。削除時間に大きな影響を与えるには、非常に大きなファイルが必要です。作業の大部分は、各ディレクトリエントリを順番に削除することです。ファイルのデータは消去されません。ファイルのコンテンツを消去するには、使用していたブロックを空きとしてマークするだけでよく、比較的高速です。

Gillesが言うように、一般的にディレクトリ内の削除の順序を予測することはできません。トップレベルのディレクトリがコマンドラインの順序で処理されることだけが予測されます。

ただし、UNIXではディレクトリが空の場合にのみ削除できるため、ディレクトリ階層が下から上に削除されることも保証されます。したがって、ディレクトリを削除するには、まずディレクトリ内のすべてを削除する必要があります。サブディレクトリが含まれている場合は、最初にコンテンツを削除する必要があります。

5
Barmar