flock -x -w 5 ~/counter.txt 'COUNTER=$(cat ~/counter.txt); echo $((COUNTER + 1)) > ~/counter.txt'
上記の例のように、flock
に複数のコマンドを渡すにはどうすればよいですか?
私が理解している限り、flock
は異なるフラグ(-xは排他、-wはタイムアウト)、次にファイルをロックし、次にコマンドを実行します。この関数に2つのコマンドを渡す方法がわからない(ロックされたファイルの内容で変数を設定してから、このファイルをインクリメントする)。
ここでの私の目標は、スクリプトがcounter.txt
ファイルにアクセスしようとするたびにファイルをロックすることにより、ファイルに多少アトミックな増分を作成することです。
シェルを明示的に呼び出します。
flock -x -w 5 ~/counter.txt sh -c 'COUNTER=$(cat counter.txt); echo $((COUNTER + 1)) > ~/counter.txt'
変更する変数は、そのシェルインスタンスに対してローカルであることに注意してください。たとえば、COUNTER
変数は呼び出し元のスクリプトで更新されません。ファイルから読み込む必要があります(ただし、その間に変更された可能性があります)、またはコマンドの出力として次のようにします。
new_counter=$(flock -x -w 5 ~/counter.txt sh -c 'COUNTER=$(cat counter.txt); echo $((COUNTER + 1)) | tee ~/counter.txt')
または、ファイル記述子を群れにすることができます
exec {counterfd}<~/counter.txt
flock -x -w 5 "$counterfd"
COUNTER=$(cat ~/counter.txt)
COUNTER=$(( COUNTER +1 ))
echo "$COUNTER" >~/counter.txt
exec {counterfd}<&-
これには、サブシェルベースのアプローチとは異なり、カウンター変数を直接使用できるという利点もあります。
flock
ツールの使い方は少しトリッキーで、manページはかなり短いです。マニュアルページには、ツールを使用する3つの方法があります。
flock [options] <file|directory> <command> [command args]
flock [options] <file|directory> -c <command>
flock [options] <file descriptor number>
この質問の言い方では、flock
の3番目の形式を必ず使用します。 flock
のmanページのさらに下に行くと、3番目の形式を使用するための正確な構文を示すいくつかの例があります。
#!/bin/bash
(
flock -n 9 || exit 1
echo "commands executed under lock..."
echo "go here..."
) 9>/tmp/mylockfile
#!/bin/bash
を追加しました。
この形式のflock
を正常に使用しました。