2011-01-22 6 views
12

可能性の重複を実行している場合は、そのスクリプトが実行されていないことを確認します私はかなりよされ、適切にバックアップする私のフォルダをcronジョブを設定している
Quick-and-dirty way to ensure only one instance of a shell script is running at a timeシェルスクリプト:すでに

誇り高いしかし、私は、バックアップからの結果を見て、私のバックアップスクリプトが複数回Cro​​ntabによって呼び出され、複数のバックアップが同時に実行されていることを発見しました。

非常に同じスクリプトが既に実行されている場合、特定のシェルスクリプトを実行しないようにする方法はありますか?

ありがとうございました

+0

同様の質問:http://stackoverflow.com/questions/ 1440967/how-do-make-sure-my-bash-script-isnt-already-running – mizo

+0

[プロセス管理](http://mywiki.wooledge.org/ProcessManagement)を参照してください。 –

答えて

33

競合状態や早期終了の問題のないソリューションは、ロックファイルを使用することです。 flockユーティリティは非常によくこれを処理し、このように使用することができます:スクリプトがすでに実行されている場合には、非0の状態ですぐに戻ります

flock -n /var/run/your.lockfile -c /your/script 

0

tmpファイルを使用できます。
名前はtmpCronBkp.a、tmpCronBkp.b、tmpCronBkp.c ...などです。あなたのバックアップスクリプトのリリース。

スクリプトの起動時に、それを作成し、最後にそれを削除...しばらく

、ファイルが存在しないか、いないとどのようなファイルが存在するかどうかを確認します。

この方法で試しましたか?

+0

私は自分自身を完全にはっきりさせるかどうか分かりませんが、すでにCRONによって呼び出されていてアクティブなシェルスクリプトが再び実行されないようにしたいのです – Industrial

+0

このファイルには開始されたプロセスのPIDが保持されます。それで、あなたはそれがまったく動いているかを知ることができます。 – akond

+0

はい、tmpファイルを確認し、ファイルが存在する場合はscritから終了できます! – elp

7

これを行うには、通常かつ簡単な方法のようなものにすることです:最後にあなたのスクリプトの先頭と

rm -f /tmp/myscript.running 

if [[ -f /tmp/myscript.running ]] ; then 
    exit 
fi 
touch /tmp/myscript.running 

を、ケース内trap機能で、それ終わりには達しません。

これにはまだいくつかの問題があります(上部の競合状態など)が、大部分の場合はそうなります。

+0

スクリプトを実行する前にスクリプトが実行されないようにします。 – unbeli

+0

@unbeli:終了時にセンチネルファイルを削除するので、それはできません。 – paxdiablo

+9

「ファイルが存在しません」と「ファイルを作成する」のTOCTOU(チェックの時間、使用時間)が原因で競合状態が発生します。アトミックメカニズムは 'mkdir /tmp/myscript.running 2>/dev/null'です。ディレクトリが存在する場合、 'mkdir'は失敗し、同時に実行されている' mkdir'コマンド(システムコール)の1つだけがカーネルによって確実に実行されます。 –

5

ロックファイルなしの良い方法:

ps | grep $0 | grep -v grep > /var/tmp/$0.pid 
pids=$(cat /var/tmp/$0.pid | cut -d ' ' -f 1) 
for pid in $pids 
do 
    if [ $pid -ne $$ ]; then 
     logprint " $0 is already running. Exiting" 
     exit 7 
    fi 
done 
rm -f /var/tmp/$0.pid 

これはクールでロックファイル、なしでそれをしません。 psを一時ファイルに書き込んで、最初のフィールド(pid#)を削り取り、自分自身を探します。私たちが別のものを見つけたら、誰かがすでに走っています。 grep $ 0は、このプログラムのインスタンスだけにリストを短縮し、grep -v grepはgrepそのものの行を取り除きます:

+1

です.pgrepを使う方が簡単です: 'pids = $(pgrep $ 0); $ pidsでのpidの – Jeremy

関連する問題