1つのプログラムで多数のネストされたサブフォルダーが作成されました。コマンドrm -fr *
を使用してそれらをすべて削除しようとしました。しかし、それは非常に遅いです。それらをすべて削除するより速い方法はありますか?
それらをそのディレクトリから削除する最も速い方法は、それらをそこから移動することです。その後、バックグラウンドで削除します。
mkdir ../.tmp_to_remove
mv -- * ../.tmp_to_remove
rm -rf ../.tmp_to_remove &
これは、現在のディレクトリがマウントされたパーティションのトップレベルではないことを前提としています(つまり、../.tmp_to_remove
が同じファイルシステム上にある)。
--
で始まるファイル/ディレクトリ名がある場合は、mv
の後の-
(ステファンによって編集されたとおり)が必要です。
上記はサブディレクトリを再帰的に処理する必要がないので、ほんの一瞬で現在のディレクトリからファイルを削除します。ファイルシステムからのツリーの実際の削除には時間がかかりますが、それが邪魔にならないため、実際の効率はそれほど重要ではありません。
rsync
は驚くほど高速でシンプルです。最初に空のディレクトリを作成する必要があります。
mkdir emptydir rsync -a --delete emptydir/yourdirectory /
yourdirectory/
は、ファイルを削除するディレクトリです。
rm -rf *
、またはより正確な同等のrm -rf -- *
の1つの問題は、シェルが最初に現在のディレクトリ内のすべての(非表示でない)ファイルを一覧表示し、それらを並べ替えてrm
に渡すことです。現在のディレクトリにあるファイルが大きいと、不要なオーバーヘッドが追加され、ファイルのリストが大きすぎると失敗する可能性もあります。
通常は、代わりにrm -rf .
を使用します(これには、隠しファイルも削除するという利点もあります)。しかし、すべてのPOSIX準拠のものを含むほとんどのrm
実装は、これを拒否します。その理由は、一部のシェル(すべてのPOSIXシェルを含む)に、.*
グロブの拡張に.
および..
が含まれるという誤った機能があるためです。つまり、rm -rf .*
は現在のディレクトリと親ディレクトリを削除することになるため、rm
は、これらのシェルのその誤った機能を回避するように変更されています。
pdksh
(および他のForsythシェル派生物)、zsh
、またはfish
のような一部のシェルには、その誤った機能はありません。 zsh
にはrm
ビルトインがあり、これはautoload zsh/files
で有効にできます。これは、zsh
の.*
に.
が含まれていないか、..
がrm -rf .
で正常に動作するためです。したがって、zsh
では、次のことができます。
autoload zsh/files
rm -rf .
Linuxでは、次のことができます。
rm -rf /proc/self/cwd/
現在のディレクトリを空にする、または:
rm -rf /dev/fd/3/ 3< some/dir
任意のディレクトリを空にします。
(末尾の/
に注意してください)
GNUシステムでは、次のことができます:
find . -delete
さて、現在のディレクトリにいくつかのエントリしかなく、ファイルの大部分がサブディレクトリにある場合、大きな違いはなく、rm -rf -- *
がおそらく最も高速になります。 rm -rf
(またはすべてのファイルを削除するもの)は、すべてのディレクトリの内容を読み取り、すべてのエントリでunlink()
を呼び出すことになるため、コストがかかることが予想されます。 unlink()
自体は、削除されたファイルのiノード、ファイルを含むディレクトリ、および一部のファイルシステムマップやその他の空き領域の変更を伴うため、非常に高価になる可能性があります。
rm
とfind
(少なくともGNU実装)は、すでに各ディレクトリのiノード番号でファイルのリストをソートしており、 ext4ファイルシステムでのパフォーマンス。これは、連続する(または互いに近い)iノードが順番に変更されたときに、基礎となるブロックデバイスへの変更の数を減らすためです。
rsync
は、ファイルを名前順に並べ替えます。名前順が偶数順と一致しない限り(ファイル名の並べ替えられたリストからファイルが作成された場合など)、パフォーマンスが大幅に低下する可能性があります。
場合によってはrsync
の方が高速である理由の1つは、ディレクトリがシンボリックリンクで置き換えられている場合に、間違ったディレクトリに下降する可能性のある競合状態を回避するための安全対策を講じていないように見えることですrm
またはfind
のように機能します。
さらに最適化するには:
ディレクトリツリーの最大の深さがわかっている場合は、それをfind
に渡すことができます。
find . -maxdepth 3 -delete
これにより、深さ3のディレクトリのコンテンツを読み込もうとするfind
を省くことができます。
最速はrm -rf dirname
。 RedHat6.4で、140520ファイルと9699ディレクトリを持つext3ファイルシステムのスナップショットマウントポイントを使用しました。 rm -rf *
は低速です。これは、最上位のディレクトリエントリにlotsのファイルがあり、シェルが拡張中でビジーであることが原因である可能性があります*
、追加のreaddirとソートが必要です。ディレクトリを上に移動し、rm -rf dirname/
。
Method Real time Sys time Variance (+/-)
find dir -delete 0m8.108s 0m3.668s 0.055s
rm -rf dir 0m7.956s 0m3.640s 0.081s
rsync -delete empty/ dir/ 0m8.305s 0m3.918s 0.029s
ノート: