web-dev-qa-db-ja.com

bashのファイルでアトミックな書き込み操作を実行する

Bash documentationthis 質問、および this 1を通過した後、アトミックな書き込み(追加)操作をどのように実行できるのか、まだわかりませんbashのファイル。複数のインスタンスで実行されるスクリプトがあり、ある時点でデータをファイルに書き込む必要があります。

echo "$RESULT" >> `pwd`/$TEMP_DIR/$OUT_FILE

同時に実行されているすべてのスクリプトからそのファイルへのすべての書き込み操作をアトミックにすることができますか(あるインスタンスのデータが別のインスタンスのデータと重複しないように)。

13
Sebi

Manの例のようにflockを使用する必要があるようです( http://linux.die.net/man/1/flock

(
flock -x 200

# Put here your commands that must do some writes atomically

) 200>/var/lock/mylockfile 

そして、アトミックでなければならないすべてのコマンドを()に入れます。

10
user17530

flockは、操作をインターロックする方法の1つです。このユーティリティはutil-linuxツールセットの一部であり、Linuxでのみ使用できます。幅広いプラットフォームで利用できる他のユーティリティは、Daniel J. Bernsteinのデーモンツールパッケージのsetlockユーティリティに基づいています。

  • setlock daemontoolsから
  • setlock Bruce Guenterのdaemontools-encoreから
  • s6-setlock Laurent Bercotのs6から
  • chpst Gerrit Papeのrunitから
  • runlock ウェインマーシャルのperpから
  • setlock noshツールセットから

これらのツールは、M。クレンコフの回答で使用されているものとは少し異なるパラダイムで動作します(flockも使用できますが、その回答では使用しません)。 setlockプログラムを呼び出して、インターロックする必要があるコマンドにchain loadします。 setlock自体がロックファイルを開いてロックし、そのファイル記述子をプロセスで開いたままにします。ロックは、そのプロセスが続く限り存続します(開いているファイル記述子を見つけて閉じることによって明示的にロックを解放するためにチェーンされた後続のコマンドを除く)。

質問の場合、出力行を生成するコマンドをインターロックする必要があります。これにより、externalechoが呼び出されることに注意してください。シェル組み込みechoコマンドの例:

setlock mylockfile echo "$ RESULT" >> ./$TEMP_DIR/$OUT_FILE

この場合、追加モードで出力ファイルを開いてインターロックする必要はありません。その場合、ロック内でそのファイルを開く必要があります。これには、 fdredir / redirfd のようなプログラムを使用する必要があります。

setlock mylockfile fdredir --append 1 "./$TEMP_DIR/$OUT_FILE" echo "$ RESULT"
outfile(){setlock mylockfile fdredir --append 1 "./$TEMP_DIR/$OUT_FILE" "$ @"; }
[…]
outfile echo "$ RESULT"
setlock mylockfile sh -c 'echo' "$ RESULT" '>> "./'$TEMP_DIR'/'$OUT_FILE'" '

もちろん、これは出力ファイルへの書き込み以外のものに一般化されます。

setlock mylockfile sh -c '…インターロック;もの…」
4
JdeBP