以前シェルスクリプトの多重起動をアドバイザリロックで防止する案を書きましたが・・・
この方法だとロックファイルが残りっぱなしになるので気持ち悪いです。。。
シェルスクリプト自身をロックすればいいかな? と思ったのですが・・・
追記で開かれた状態で実行しようとすると bad interpreter: Text file busy
となり、排他制御の目的は達せられてもやっぱり気持ち悪いです。
bash hoge.sh
などと呼べば回避できましたが、それはそれでやっぱり気持ち悪いです。./hoge.sh
と書きたいです。
そこで、シェルスクリプト自身を読み込みで開いて排他ロックするようにしてみました。
lock.sh
exec {fd}<$0
flock -w 1 -x $fd || {
echo "duplicate process.">&2
exit 1
}
次のように使います。
hoge.sh
#!/bin/bash
source lock.sh
# 適当なファイルを 読み込み → インクリメント → 書き戻す
# 排他制御しないと正しくカウントされない
num=$(cat datafile)
usleep 1000
echo $(($num + 1)) > datafile
次のようにテストしてみます。
echo 100000 > datafile
seq 100 | xargs -P 100 -L 1 ./hoge.sh
cat datafile
上手くカウントできています。
100100
もちろん source lock.sh
の部分をコメントアウトするとまともにカウントされません。