web-dev-qa-db-ja.com

Unix:デイリービルドをクリーンアップするための高速な「ディレクトリの削除」

ディレクトリを削除してから送信するより速い方法はありますか?

rm -r -f *directory*

?私たちの毎日のクロスプラットフォームビルドは本当に巨大なので、私はこれを求めています(たとえば、ビルドごとに4GB)。そのため、一部のマシンのハードディスクは頻繁にスペースを使い果たしています。

つまり、これは、AIXおよびSolarisプラットフォームの場合です。

たぶん、これらのプラットフォームでディレクトリ削除のための「特別な」コマンドがありますか?

貼り付け-編集(私自身の別の回答を質問に移動しました):

私は一般的に、なぜ 'rm -r-f'がとても遅いのか疑問に思っています。 'rm'は '..'または '。'を変更する必要はありません。ファイルシステムエントリの割り当てを解除するファイル。

何かのようなもの

mv *directory* /dev/null

いいだろう。

19
anon

ファイルシステムからディレクトリを削除するには、rmが最速のオプションです。 Linuxでは、RAMディスクでビルド(数GB)を実行することがあり、削除速度は非常に優れています:)さまざまなファイルシステムを試すこともできますが、AIX/Solarisでは多くのオプションがない場合があります...

ディレクトリ$ di​​rを空にすることが目標である場合now、名前を変更し、後でバックグラウンド/ cronジョブから削除できます。

mv "$dir" "$dir.old"
mkdir "$dir"
# later
rm -r -f "$dir.old"

もう1つのトリックは、$ dir用に別のファイルシステムを作成し、それを削除する場合は、ファイルシステムを再作成するだけです。このようなもの:

# initialization
mkfs.something /dev/device
mount /dev/device "$dir"


# when you want to delete it:
umount "$dir"
# re-init
mkfs.something /dev/device
mount /dev/device "$dir"
23
Balázs Pozsár

私はこのトリックのソースを忘れましたが、それは機能します:

EMPTYDIR=$(mktemp -d)
rsync -r --delete $EMPTYDIR/ dir_to_be_emptied/
18
yegle

少なくともAIXでは、論理ボリュームマネージャーであるLVMを使用する必要があります。すべてのシステムは、すべての物理ハードドライブを単一のボリュームグループにバンドルし、そこから1つの大きなホンキンファイルシステムを作成します。

このようにして、物理デバイスをマシンに自由に追加し、ファイルシステムのサイズを必要に応じて増やすことができます。

私が見たもう1つの解決策は、各ファイルシステムにごみ箱ディレクトリを割り当て、mvfindcronジョブの組み合わせを使用してスペースの問題に取り組むことです。

基本的に、10分ごとに実行されて実行されるcronジョブがあります。

rm -rf /trash/*
rm -rf /filesys1/trash/*
rm -rf /filesys2/trash/*

次に、そのファイルシステム上の特定のディレクトリをリサイクルする場合は、次のようなものを使用します。

mv /filesys1/overnight /filesys1/trash/overnight

そして、次の10分以内に、ディスク容量が回復し始めます。 filesys1/overnightディレクトリは、ゴミ箱に移動されたバージョンの削除が開始される前でも、すぐに使用できるようになります。

ごみ箱ディレクトリは、削除したいディレクトリと同じファイルシステム上にあることが重要です。そうしないと、比較的すばやく移動するのではなく、大量のコピー/削除操作を手に入れることができます。

5
paxdiablo

rm -r directoryは、深さ優先探索からdirectoryまでを繰り返し、ファイルを削除し、戻る途中でディレクトリを削除することで機能します。空でないディレクトリは削除できないため、削除する必要があります。

長くて退屈な詳細:各ファイルシステムオブジェクトは、ファイルシステム内のiノードで表されます。このiノードには、ファイルシステム全体のフラットなiノード配列があります。[1]最初に子を削除せずにdirectoryを削除した場合、子は割り当てられたままになりますが、子へのポインタはありません。 (fsckは、ファイルシステムの損傷を表すため、実行時にそのようなことをチェックします。)

[1]これは、すべてのファイルシステムに厳密に当てはまるわけではなく、説明どおりに機能するファイルシステムが存在する場合もあります。ガベージコレクターのようなものが必要になる可能性があります。ただし、私が知っている一般的なものはすべてact fsオブジェクトのようにinodeによって所有され、ディレクトリは名前とinodeの番号のペアのリストです。

3
Tommy McGuire

rm -rfが遅い場合は、「同期」オプションなどを使用している可能性があります。これは、ディスクへの書き込みが多すぎます。通常のオプションを使用するLinuxext3では、rm -rfは非常に高速です。

LinuxおよびおそらくさまざまなUnixenでも機能する高速削除の1つのオプションは、次のようなループデバイスを使用することです。

hole temp.img $[5*1024*1024*1024]  # create a 5Gb "hole" file
mkfs.ext3 temp.img
mkdir -p mnt-temp
Sudo mount temp.img mnt-temp -o loop

「穴」プログラムは、ディスクに割り当てられたブロックではなく「穴」を使用して大きな空のファイルを作成するために自分で作成したプログラムです。これははるかに高速で、本当に必要になるまでディスク領域を使用しません。 http://sam.nipl.net/coding/c-examples/hole.c

GNU coreutilsには同様のプログラム "truncate"が含まれていることに気づきました。そのため、これを使用してイメージを作成できます。

truncate --size=$[5*1024*1024*1024] temp.img

これで、mnt-tempでマウントされたイメージを、ビルド用の一時ストレージとして使用できます。使い終わったら、これを実行して削除します。

Sudo umount mnt-temp
rm test.img
rmdir mnt-temp

大きなファイルを1つ削除する方が、小さなファイルをたくさん削除するよりもはるかに高速であることがわかると思います。

私の「hole.c」プログラムをコンパイルする必要がない場合は、ddを使用できますが、これははるかに低速です。

dd if=/dev/zero of=temp.img bs=1024 count=$[5*1024*1024]  # create a 5Gb allocated file
3
Sam Watkins

私もこれを調べていました。

600,000以上のファイルを含むディレクトリがありました。

エントリが多すぎるため、rm *は失敗します。

find . -exec rm {} \;は素晴らしく、5秒ごとに最大750個のファイルを削除しました。別のシェルを介してrmレートをチェックしていました。

そこで、代わりに、一度に多くのファイルをrmする短いスクリプトを作成しました。これは、5秒ごとに約1000個のファイルを取得しました。効率を上げるために、できるだけ多くのファイルを1rmコマンドに入れるという考え方です。

#!/usr/bin/ksh
string="";
count=0;
for i in $(cat filelist);do
    string="$string $i";
    count=$(($count + 1));
  if [[ $count -eq 40 ]];then
    count=1;
    rm $string
    string="";
  fi
done
2
Scott

ディレクトリを削除するために引用したように、実際には「rm-rf」以外に何もないと思います。

手動で何度も繰り返すのを避けるために、次のような「十分に古い」場合、ビルドルートディレクトリのすべてのビルドディレクトリを再帰的に削除するスクリプトを毎日cronすることができます。

find <buildRootDir>/* -Prune -mtime +4 -exec rm -rf {} \;

(ここで、mtime +4は、「4日より古いファイル」を示します)

もう1つの方法は、ビルダーを構成して(そのようなことが許可されている場合)、以前のビルドを現在のビルドでクラッシュさせることです。

2

Perl -e'for(<*>){((stat)[9] <(unlink))} 'を使用してください。以下のリンクを参照してください: http://www.slashroot.in/which-is-the -fastest-method-to-delete-files-in-linux

2
rohit_gupta

Solarisでは、これが私が見つけた最速の方法です。

find /dir/to/clean -type f|xargs rm

パスが奇数のファイルがある場合は、

find /dir/to/clean -type f|while read line; do echo "$line";done|xargs rm 
1
smoltz

Rmよりも高速な小さなJavaアプリケーションRdPro(再帰ディレクトリパージツール)をコーディングしました。rootで指定されたターゲットディレクトリを削除することもできます。Linux/ UnixとWindowsの両方で動作します。コマンドラインバージョンとGUIバージョンの両方があります。

https://github.com/mhisoft/rdpro

0
Tony

Windowsで300,000を超えるファイルを削除する必要がありました。 cygwinをインストールしました。幸いなことに、私はデータベースにすべてのプライマリディレクトリを持っていました。 forループを作成し、行の入力とrm-rfを使用して削除します

0
gnuyoga

フォルダ内のfind ./ -deleteを使用して空にすると、約10分で620000ディレクトリ(合計サイズ)100GBが削除されました。

出典:このサイトのコメント https://www.slashroot.in/comment/1286#comment-1286

0
Arzhh

AWS EBS 1 TBディスク(ext3)の数十のディレクトリから700ギガバイトを削除してから、残りを新しい200ギガバイトのXFSボリュームにコピーする必要がありました。そのボリュームを100%waのままにしておくのに何時間もかかりました。ディスクIOとサーバー時間は空いていないので、これはディレクトリごとにほんの一瞬しかかかりませんでした。

ここで、/ dev/sdbは、任意のサイズの空のボリュームです。

directory_to_delete =/ebs/var/tmp /

マウント/ dev/sdb $ directory_to_delete

Nohup rsync -avh/ebs// ebs2 /

0
Mark306