18

同じスクリプトの 2 つのインスタンスが同時に実行されるのを回避する一般的な方法は、次のようになります。

[ -f ".lock" ] && exit 1
touch .lock
# do something
rm .lock

競合状態を回避して、シェルスクリプトからファイルをロックするより良い方法はありますか? 代わりにディレクトリを使用する必要がありますか?

4

5 に答える 5

24

はい、実際にサンプル スクリプトには競合状態があります。別の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
于 2008-11-28T12:23:32.037 に答える
10

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 です。

于 2009-10-15T11:14:12.257 に答える
4

スクリプトをロックします (並列実行に対して)

http://wiki.bash-hackers.org/howto/mutex

ご参考までに。

于 2011-03-06T09:13:05.353 に答える
-1

私はもっ​​と簡単な解決策を見つけたようです:man lockfile

于 2008-11-28T12:28:34.693 に答える