実行可能ファイルが強制終了されたときにディレクトリを自動的に削除する方法


9

多くの場合、一時ファイルの書き込み/読み取りが必要な実行可能ファイルを実行します。通常、一時ディレクトリを作成し、そこで実行可能ファイルを実行し、スクリプトが完了したらディレクトリを削除します。

実行ファイルが殺されてもディレクトリを削除したいのですが。私はそれを包み込もうとしました:

#!/bin/bash
dir=$(mktemp -d /tmp/foo.XXXXXXX) && cd $dir && rm -rf $dir
/usr/local/bin/my_binary

ときにmy_binaryスクリプトがそれを保持する最後のプロセスであるようダイは、最後のプロセスのカーネルでは、ディレクトリを削除しますinode。削除したディレクトリにファイルを作成できません。

#!/bin/bash
dir=$(mktemp -d /tmp/foo.XXXXXXX) && cd $dir && rm -rf $dir
touch file.txt

出力 touch: file.txt: No such file or directory

私が思いつくことができる最高のものは、プロセスが死んだときに一時ディレクトリを削除し、最も一般的なシグナルをキャッチして、cronでクリーンアッププロセスを実行することです。

#!/bin/bash
dir=$(mktemp -d /tmp/d.XXXXXX) && cd "$dir" || exit 99
trap 'rm -rf "$dir"' EXIT
/usr/local/bin/my_binary

現在のバイナリが死んだときに自動的に削除される本当に一時的なディレクトリを作成する簡単な方法はありますか?


1
cleanupmktempが完了する前に実行される小さなウィンドウがあることに注意してください。unset dirトラップを設定する前に、必要な場合があります。
ステファンChazelas

これを処理し、mktempの失敗を処理するようにスクリプトを更新しました。
ホアキンクエンカアベラ2014

出口は必須だと思いました。修繕。
ホアキンクエンカアベラ2014

最後の例ではcronについて触れていますが、cronとは関係ありません。その最後の例は、最もフェイルセーフでもあります。処理できないのはSIGKILLだけです。
Patrick 14

簡潔にするために実行しているcronスクリプトは含めませんでした。1時間以上前のdirsに一致してそれらをrmするのは、そのパターンの発見です。sigkillのケース、またはスクリプトの途中での残忍なシャットダウンまでもカバーする解決策があるかどうかを知りたいです。
ホアキンクエンカアベラ2014

回答:


3

あなたの最後の例は最もフェイルセーフです。

trap 'rm -rf "$dir"' EXIT

これは、シェル自体がまだ機能している限り実行されます。基本的に、SIGKILLは、シェルが強制的に終了されるため、処理できない唯一のものです。
(おそらくSIGSEGVも試しませんでしたが、キャッチできます)

それ自体をクリーンアップするためにシェルに任せない場合、他に可能な唯一の選択肢は、カーネルに実行させることです。これは通常カーネル機能ではありませんが、実行できるトリックが1つありますが、それ自体に問題があります。

#!/bin/bash
mkdir /tmp/$$
mount -t tmpfs none /tmp/$$
cd /tmp/$$
umount -l /tmp/$$
rmdir /tmp/$$

do_stuff

基本的には、tmpfsマウントを作成してから、レイジーにアンマウントします。スクリプトが完了すると、削除されます。
過度に複雑なこと以外の欠点は、アンマウントする前にスクリプトが何らかの理由で停止した場合、マウントが配置されないことです。
これはメモリを消費するtmpfsも使用します。ただし、プロセスをより複雑にしてループファイルシステムを使用し、マウント後にファイルを削除することもできます。


究極的にtrapは、シンプルさと安全性に関しては最高です。そして、スクリプトが定期的にSIGKILLされているのでない限り、私はそれを使い続けます。


トラップがその前後に配置されているかどうかは重要mktempですか?トラップがの直前に配置されている場合、トラップのmktemp後での前に終了信号が受信されたmktempとしても、rm -rfコマンドが空の引数で実行され、何も実行されない場合があります。しかし、トラップがの後にある場合、mktemp一時ディレクトリが残される可能性の小さなウィンドウが存在する可能性があります。または私は完全にオフベースですか?
ワイルドカード2016年

1

組み込みの待機を使用して、バックグラウンドジョブが完了するまで待機できます。

blah &
wait
rm -rf $DIR

しかし、それはと同等blah; rm -rf $DIRですよね?スクリプトを強制終了すると$ DIRをリークする問題があります。
ホアキンクエンカアベラ2014

子スクリプトが強制終了された場合、親スクリプトはその後もクリーンアップを続けます。親スクリプトも削除された場合、そうです、ディレクトリは取り残されます。
マシュークライン14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.