はい、実際にサンプル スクリプトには競合状態があります。 bash の noclobber
を使用できます -f
の間に別のスクリプトが忍び込んだとき、レースの場合に失敗するためのオプション テストと touch
.
以下は、メカニズムを説明するサンプル コード スニペット (この記事に触発されたもの) です:
if (set -o noclobber; echo "$$" > "$lockfile") 2> /dev/null;
then
# This will cause the lock-file to be deleted in case of a
# premature exit.
trap 'rm -f "$lockfile"; exit $?' INT TERM EXIT
# Critical Section: Here you'd place the code/commands you want
# to be protected (i.e., not run in multiple processes at once).
rm -f "$lockfile"
trap - INT TERM EXIT
else
echo "Failed to acquire lock-file: $lockfile."
echo "Held by process $(cat $lockfile)."
fi
flock コマンドを試してください:
exec 200>"$LOCK_FILE"
flock -e -n 200 || exit 1
ロックファイルがロックされている場合は終了します。これはアトミックであり、NFS の最近のバージョンで動作します。
私はテストをしました。 0 を含むカウンター ファイルを作成し、2 つのサーバーで同時に 500 回、ループ内で次のコマンドを実行しました:
#!/bin/bash
exec 200>/nfs/mount/testlock
flock -e 200
NO=`cat /nfs/mount/counter`
echo "$NO"
let NO=NO+1
echo "$NO" > /nfs/mount/counter
1 つのノードがロックを求めて他のノードと競合していました。両方の実行が終了したとき、ファイルの内容は 1000 でした。何度も試しましたが、常に機能します!
注:NFS クライアントは RHEL 5.2 で、使用されるサーバーは NetApp です。
スクリプトをロックします (並列実行に対して)
http://wiki.bash-hackers.org/howto/mutex
ご参考までに。