rm -rfを使用して大容量ファイル(最大サイズ20 GB)をすばやく削除すると、失敗して時々停止することがありますか?

rm -rfを使用して大容量ファイル(最大サイズ20 GB)をすばやく削除すると、失敗して時々停止することがありますか?

rm -rf .* を使用してサブディレクトリを削除しようとしましたが、サブフォルダの削除に失敗しました。最大5000個まで処理できますが、10000個以上のサブディレクトリを一度に削除することはできません。サブディレクトリからファイルを削除してからサブディレクトリを削除するスクリプトを作成しました。

    # loop & print a folder recusively,
print_folder_recurse() {
for i in "$1"/*;do
    if [ -d "$i" ];then
        print_folder_recurse "$i"
        #echo "dir: $i"
    elif [ -f "$i" ]; then
        #echo "file: $i"
        rm -rf $i
    fi
done
#echo "dir: $1"
if [[ "$1" != "$path" ]]; then
    #echo "dir : $1"
    rm -rf $1o
fi

}

注:このスクリプトも時々失敗します。ディレクトリサイズは常に20 GBに制限されるわけではありません。今後はるかに大きくなる可能性があります。

この種の問題を処理するより良い方法を知っているLinuxの専門家はいますか?

答え1

問題は、削除するアイテムのサイズではなく数量です。

:を試してもrm -rf *スクリプトでもfor i in "$1"/*;do、:shellには何千ものファイルパスを見つけてメモリに保存する拡張*が必要です。数値が大きすぎると、速度が非常に遅くなるか失敗します(エラーメッセージとともに)。

簡略化してスクリプトで直接使用する必要があります rm -rf "${1:-missing_directory_name}"。唯一のコマンドとして:rmはサブファイル検索を独自に処理します。

代替方法は、find "${1:-missing_directory_name}" - type f -depth -print0 | xargs -0 -n 100 rmexatファイルの数に関係なく、findが100個のファイル名を出力するたびにrmを呼び出して、rmに追加される引数の数を制限することです。その後、find "${1:-missing_directory_name}" -type f -depth -print0 | xargs -n 100 rmdir空でないディレクトリを最初に削除したくない場合は、「最も深いディレクトリ」から始めて、残りのディレクトリに対してrmdirなどの他のクエリを実行します。 (しかし、最初の解決策はこれらすべてを1rmで行い、最終的に最も効率的であることが証明されます)

スクリプトの実行中に他のターミナルウィンドウで次のことができます。 df -i directory_nameディレクトリ内のファイルが削除されるにつれて、inodeの数が急激に減少することを確認できます。 (df​​-iはディレクトリ名を含むファイルシステムのすべてのinodeを表示するため、そのファイルシステムの他のファイルが別のディレクトリまたは親ディレクトリにある可能性があるため、0で終わらない可能性があります。

他の方法もたくさんあります(最近の調査結果によると、xargsなどを使わない他の方法もあります)。

アイデアは同じままです。拡張するファイル数が多すぎる場合は、シェル拡張を使用しないでください。

関連情報