私が知っているように
find <dir> -type f -exec rm {} \;
大量のファイル(サブフォルダーを含む合計ファイル)を削除するのに最適なバリアントではありません。ファイルの量が少ない場合はうまく機能しますが、サブフォルダーに10 mlns以上のファイルがある場合は、サーバーがハングする可能性があります。
この問題を解決するための特定のLinuxコマンドを知っている人はいますか?
奇妙に見えるかもしれませんが:
$ rm -rf <dir>
次に、bashスクリプトの例を示します。
#!/bin/bash
local LOCKFILE=/tmp/rmHugeNumberOfFiles.lock
# this process gets ultra-low priority
ionice -c2 -n7 -p $$ > /dev/null
if [ $? ]; then
echo "Could not set disk IO priority. Exiting..."
exit
fi
renice +19 -p $$ > /dev/null
if [ $? ]; then
echo "Could not renice process. Exiting..."
exit
fi
# check if there's an instance running already. If so--exit
if [ -e ${LOCKFILE} ] && kill -0 `cat ${LOCKFILE}`; then
echo "An instance of this script is already running."
exit
fi
# make sure the lockfile is removed when we exit. Then: claim the lock
trap "command rm -f -- $LOCKFILE; exit" INT TERM EXIT
echo $$ > $LOCKFILE
# also create a tempfile, and make sure that's removed too upon exit
tmp=$(tempfile) || exit
trap "command rm -f -- '$tmp'" INT TERM EXIT
# ----------------------------------------
# option 1
# ----------------------------------------
# find your specific files
find "$1" -type f [INSERT SPECIFIC SEARCH PATTERN HERE] > "$tmp"
cat $tmp | rm
# ----------------------------------------
# option 2
# ----------------------------------------
command rm -r "$1"
# remove the lockfile, tempfile
command rm -f -- "$tmp" $LOCKFILE
このスクリプトは、他の実行中のプロセスが可能な限り影響を受けないようにするために、独自のプロセス優先度とdiskIO優先度を非常に低い値に設定することから始まります。
次に、それが実行されている唯一のそのようなプロセスであることを確認します。
スクリプトのコアは本当にあなたの好み次第です。rm -r
dir全体を無差別に削除できることが確実な場合に使用できます(オプション2)。またはfind
、より具体的なファイル削除に使用できます(オプション1、コマンドラインオプション "$ 2"およびonw。を使用する場合があります)。
上記の実装では、オプション1(find
)は最初にすべてを一時ファイルに出力するため、rm
関数は、によって検出された各ファイルの後ではなく、1回find
だけ呼び出されます。ファイルの数が実際に膨大な場合、これは大幅な時間の節約になります。欠点としては、一時ファイルのサイズが問題になる可能性がありますが、これは文字通り数十億のファイルを削除する場合にのみ発生する可能性があります。さらに、diskIOの優先度が非常に低いため、一時ファイルの後に1つを使用するrm
と合計でfind (...) -exec rm {} \;
オプションを使用するよりも遅い。いつものように、少し実験して、ニーズに最適なものを確認する必要があります。
編集:user946850によって提案されているように、一時ファイル全体をスキップしてを使用することもできます
find (...) -print0 | xargs -0 rm
。find
コマンドが完全に終了するまで、一致するすべてのファイルへのすべてのフルパスがRAMに挿入されるため、これはメモリフットプリントが大きくなります。利点:一時ファイルへの書き込みによる追加のファイルIOはありません。どちらを選択するかは、ユースケースによって異なります。
(-r
再帰的)スイッチは、サブディレクトリを含む、ディレクトリの下のすべても削除します。(コマンドはディレクトリを削除せず、ファイルのみを削除します。)
find
アプローチをスピードアップすることもできます。
find -type f -print0 | xargs -0 rm
これらのコマンドをすべて試しましたが、削除プロセスがディスクをロックしていて、他のプロセスがディスクにアクセスできないため、ディスクにアクセスしようとするプロセスが大量に発生し、問題が悪化していました。「iotop」を実行して、プロセスが使用しているディスクIOの量を確認します。
これが私の問題を解決したPythonスクリプトです。一度に500個のファイルを削除し、2秒の休憩を取って他のプロセスに処理を任せてから、続行します。
import os, os.path
import time
for root, dirs, files in os.walk('/dir/to/delete/files'):
i = 0
file_num = 0
for f in files:
fullpath = os.path.join(root, f)
i = i + 1
file_num = file_num + 1
os.remove(fullpath)
if i%500 == 1:
time.sleep(2)
print "Deleted %i files" % file_num
これが一部の人々に役立つことを願っています。
非常に大きなファイルツリー(私の場合は多くのPERFORCEブランチ)のスペース制限の問題に対処する必要がある場合、検索と削除のプロセスの実行中にハングすることがあります-
これは、特定のファイル( "ChangesLog.txt")を持つすべてのディレクトリを検索し、 2日より古いディレクトリをすべて並べ替えて、最初に一致したディレクトリを削除するように毎日スケジュールするスクリプトです(各スケジュールで新しい一致が発生する可能性があります) )::
bash -c "echo @echo Creating Cleanup_Branch.cmd on %COMPUTERNAME% - %~dp0 > Cleanup_Branch.cmd"
bash -c "echo -n 'bash -c \"find ' >> Cleanup_Branch.cmd"
rm -f dirToDelete.txt
rem cd. > dirToDelete.txt
bash -c "find .. -maxdepth 9 -regex ".+ChangesLog.txt" -exec echo {} >> dirToDelete.txt \; & pid=$!; sleep 100; kill $pid "
sed -e 's/\(.*\)\/.*/\1/' -e 's/^./"&/;s/.$/&" /' dirToDelete.txt | tr '\n' ' ' >> Cleanup_Branch.cmd
bash -c "echo -n '-maxdepth 0 -type d -mtime +2 | xargs -r ls -trd | head -n1 | xargs -t rm -Rf' >> Cleanup_Branch.cmd"
bash -c 'echo -n \" >> Cleanup_Branch.cmd'
call Cleanup_Branch.cmd
要件に注意してください。
適度に最新バージョンのfind(4.2.3以降)を使用している場合は、-deleteフラグを使用できます。
find <dir> -type f -delete
バージョン4.2.12以降を使用している場合は、\+
-exec修飾子を使用してxargsスタイルのコマンドラインスタッキングを利用できます。/bin/rm
このように、ファイルごとに個別のコピーを実行する必要はありません。
find <dir> -type f -exec rm {} \+
前のコマンドは適切です。
rm -rf directory/
また、1つのフォルダー内の数十億のファイルに対してより高速に動作します。やってみました。
大量のファイルをできるだけ早く削除したい場合は、次のことを試してください。
find . -type f -print0 | xargs -P 0 -0 rm -f
この-P
オプションはxargs
、可能な限り多くのプロセスを使用することに注意してください。
mv large_folder /tmp/.
sudo reboot
mvへの呼び出しは高速です-ラベルを変更するだけです。システムを再起動すると、可能な限り最速の方法で/ tmpフォルダーがクリアされます(再度マウントしますか?)。
空のディレクトリを作成し、空にする必要のあるディレクトリにRSYNCすることができます。タイムアウトとメモリアウトの問題を回避します