進行状況を見ながらディレクトリから数十億のファイルを削除する


36

正式にはすべてJPEGファイルである数十億のファイルがある30 TBのディレクトリがあります。私はこのようなファイルの各フォルダーを削除しています:

sudo rm -rf bolands-mills-mhcptz

このコマンドは実行されるだけで、機能しているかどうかは表示されません。

ファイルを削除しているのか、コマンドの現在の状態を確認したいです。


19
答えではありません:保持したいものをバックアップし、フォーマットし、保持したいものを復元する方が速い場合があります。他の回答: unix.stackexchange.com/questions/37329/...
エリック・タワーズ

2
どの特定のファイルが削除されたかを知るのではなく、単に進行状況を知りたい場合は、「df / dev / sd_whatever_the_drive_is」を実行できます。
jamesqf 16

11
1つのディレクトリに何十億ものファイルができたのはどうしてですか??
モニカと

1
@MichaelHamptonただし、ファイルが個別のデータセットでない場合は、時間がかかる場合があります。(ZFSオン)serverfault.com/questions/801074/...
v7d8dpo4

5
何十億ものファイルですか?試してくださいrm -ri。楽しいですよ!
OldBunny2800 16

回答:


98

を使用rm -vして、rmファイルごとに1行削除して印刷することができます。このように、rmファイルを削除するために実際に機能していることがわかります。しかし、数十億のファイルがある場合、表示されるのrmはまだ機能していることだけです。すでに削除されたファイルの数と残っているファイルの数はわかりません。

このツールpvは、進行状況の推定に役立ちます。

http://www.ivarch.com/programs/pv.shtml

ここでは、起動する方法をであるrmとのpv出力例で

$ rm -rv dirname | pv -l -s 1000 > logfile
562  0:00:07 [79,8 /s] [====================>                 ] 56% ETA 0:00:05

この不自然な例pvでは、1000ファイルがあることを伝えました。からの出力pvは、562がすでに削除されており、経過時間が7秒であり、完了までの推定が5秒であることを示しています。

いくつかの説明:

  • pv -l作るpv改行の代わりに、バイトカウントします
  • pv -s numberpv合計が何であるかを教えてくれるので、見積もりが得られます。
  • logfile最後のリダイレクトは、クリーンな出力用です。それ以外の場合、からのステータス行はからpvの出力と混同されrm -vます。ボーナス:削除されたもののログファイルがあります。ただし、ファイルが大きくなることに注意してください。/dev/nullログが必要ない場合は、リダイレクトすることもできます。

ファイルの数を取得するには、次のコマンドを使用できます。

$ find dirname | wc -l

また、数十億のファイルがある場合、これには長い時間がかかる場合があります。pvここでも使用できます。

$ find dirname | pv -l | wc -l
278k 0:00:04 [56,8k/s] [     <=>                                              ]
278044

ここでは、278k個のファイルをカウントするのに4秒かかったと言っています。end(278044)での正確なカウントはからの出力ですwc -l

カウントを待ちたくない場合は、ファイルの数を推測するか、pv推定せずに使用できます。

$ rm -rv dirname | pv -l > logfile

このように、終了する見積もりはありませんが、少なくとも削除されたファイルの数は表示されます。/dev/nullログファイルが不要な場合にリダイレクトします。


ニピック:

  • 本当に必要sudoですか?
  • 通常、rm -r再帰的に削除するには十分です。必要はありませんrm -f

5
の素晴らしい使用法はpv、数十億のファイルを数えるのにそれほど費用がかからないと仮定します;-)。(rm測定するのと同じくらい時間がかかるかもしれません!)
スティーブンキット

7
@StephenKittこれは、Windowsファイルユーティリティについて本当に私(および他の多くの人々)を悩ませるものです:それは常に、ドライブがプロセッサよりはるかに遅い場合を除き、削除する前に必ずファイルの数とサイズをカウントします実際の削除限り!
wizzwizz4 16

@ wizzwizz4確かに!よりそれにもっとありますそのIIRCしかし-それはということを確認することができます削除する前に、すべてを削除何かを、「全か無か」である削除の可能性を高めるために。何年も前に、私はWindows用のファイルシステムドライバーを書いた。(フォルダーの作成には、新しいフォルダー内のファイルの書き込みと削除が含まれることを覚えています!)
Stephen Kitt

7
@StephenKittたぶん私は間違っているかもしれませんが、ディスクアクセス以外のボトルネックは端末出力ではありませんか?pv入力にもかかわらず、1秒に1回だけ進行状況バーを更新すると思います。そのため、端末は毎秒トンではなく1行だけを表示する必要があります。pv遭遇する改行ごとにカウンタをインクリメントするだけです。これは、行の折り返しを行うよりも高速である必要があります。端末で行を表示する場合はどうでしょう。pvこのように実行すると、ファイルの削除が単により速くなると思いますrm -rv
JOL

1
@skywinderrm -rv dirname | pv -l -s $(find dirname | wc -l) > logfile
レスマナ

28

lesmanaの答えをチェックしてください。それは私のものよりもはるかに優れています。特に最後のpv例では、の代わりにrmを指定した場合、元のサイレントよりも長くかかりません。/dev/nulllogfile

あなたrmがオプションをサポートしていると仮定すると(おそらくLinuxを実行しているのでそれをサポートします)、冗長モードで実行できます-v

sudo rm -rfv bolands-mills-mhcptz

多くのコメンターによって指摘されているように、端末によって生成および表示される出力の量のため、これは非常に遅い可能性があります。代わりに、出力をファイルにリダイレクトできます。

sudo rm -rfv bolands-mills-mhcptz > rm-trace.txt

のサイズを監視しますrm-trace.txt


5
これにより、すべての出力が生成されて端末にレンダリングされるため、実際に削除の速度が低下する可能性があります:)
rackandboneman

2
もちろん遅くなります。ファイルへの数十億行の書き込みは、ゼロ時間では発生しません。
user207421

23

別のオプションは、ファイルシステム上のファイル数が減少するのを監視することです。別のターミナルで次を実行します:

watch  df -ih   pathname

使用済みiノード数はrm、進行するにつれて減少します。(ファイルが主に複数のリンクを持たない限り、例えば、ツリーがで作成された場合cp -al)。これは、ファイル数(およびディレクトリ)の観点から削除の進行状況を追跡します。 dfwithout -iは、使用されるスペースの観点から追跡します。

また、iostat -x 41秒あたりのI / O操作(およびkiB / sですが、それは純粋なメタデータI / Oにはあまり関係ありません)を表示するために実行することもできます。


rm現在作業中のファイルについて知りたい場合は、そのファイルに添付straceして、unlink()システム呼び出し(およびgetdents)が端末で吐き出すのを見ることができます。例えばsudo strace -p $(pidof rm)。中断することなく^c、straceからデタッチできrmます。

rm -rディレクトリをツリーに変更して削除すると忘れてしまいます。もしそうなら、あなたは見ることができます/proc/<PID>/cwd。その/proc/<PID>/fdあなたは何を見ている時に見ることができるので、かもしれないが、多くの場合、ディレクトリは、オープンfdとしているrmプロセスが現在見ています。


2
df -ih確かに、rm進行状況を見るための素敵で安価な方法です。
スティーブンキット

ところで、これはBTRFSでは機能しません。BTRFSでは、使用済みiノード数は常にゼロです。:( FAT32のために同じですが、あなたはおそらく、あなたの上のファイルの数十億持たない/bootEFIシステムパーティションを。
ピーター・コルド

4

上記はすべての使用rmに答えますが、rm実際に大量のファイルを削除するのは非常に遅いことがあります。最近、.tarアーカイブから〜100Kファイルを抽出するとき、実際にそれらを削除するよりも時間がかからなかったことがわかりました。これは実際にはあなたが尋ねた質問に答えませんが、問題に対するより良い解決策は、この質問に対する賛成の回答の1つなど、別の方法を使用してファイルを削除することです。

私の個人的なお気に入りの方法は使用することrsync -a --deleteです。この方法は、その質問に対する最も賛成の答えよりも使いやすさの価値があるほど十分に高速であることがわかりました。著者は、コンパイルする必要があるCプログラムを作成しました。(これは、処理中のすべてのファイルを標準出力に出力することに注意してくださいrm -rv。これにより、プロセスが驚くほど遅くなる可能性があります。この出力が必要ない場合はrsync -aq --delete、代わりに出力を使用またはファイルにリダイレクトしてください。)

その答えの著者は言います:

プログラムは(私のシステム上で)43秒で1000000個のファイルを削除します。これに最も近いプログラムはrsync -a --deleteで、60秒かかりました(順番に削除も行いますが、効率的なディレクトリルックアップは実行しません)。

私はこれが私の目的に十分であることを発見しました。少なくともext4を使用している場合、その答えからも潜在的に重要です:

予見されるように、影響を受けるディレクトリを削除してから再作成する必要があります。ディレクトリのサイズは大きくなるだけで、ディレクトリのサイズが原因で内部にいくつかのファイルがあってもパフォーマンスが低下する可能性があります。


ハァッ、私は期待していたrm、そして/またはfind --delete効率的でした。削除中のBツリーの再バランスを回避するためのソート順での削除に関する興味深い点。他のファイルシステムにどれだけ当てはまるかわかりません。XFSは、ディレクトリごとに数百万のファイルがあるため、あまり良くありません。BTRFSについてのIDKですが、私はそれがそのようなことには良いかもしれないという印象を受けています。
ピーターコーデス

その2番目の引用は、ファイルシステムのタイプに依存しません...
Menasheh

@Menasheh良い点、私はそれを自分の答えに編集しました。
Hitechcomputergeek 16

3

できることの1つは、rmプロセスをバックグラウンドで起動し(出力なしで速度が低下しないようにする)、その後、単純な(a)コマンドでフォアグラウンドで監視することです。

pax> ( D=/path/to/dir ; rm -rf $D & while true ; do
...>   if [[ -d $D ]] ; then
...>     echo "$(find $D | wc -l) items left"
...>   else
...>     echo "No items left"
...>     break
...>   fi
...>   sleep 5
...> done )

27912 items left
224 items left
No items left

pax> _

find/wcコンボは、あなたが望むの単位を与えることができる任意のツールに置き換えることができます。


(a)まあ、核物理学、リーマン仮説、またはクリスマスのために妻を買うものと比較して、比較的簡単です:-)


0

少し前に、行が印刷される速度を印刷するために何かを書きました。実行できrm -rfv | ./counter、1秒あたりの行数を印刷します。直接的な進歩ではありませんが、進捗率に関するフィードバックを提供しますrm。おそらく、ネットワークファイルシステムなどに迷い込んでいるのでしょうか。

コードへのリンクはこちらです:

http://www.usenix.org.uk/code/counter-0.01.tar.gz

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