flockに複数のコマンドを渡す


11
flock -x -w 5 ~/counter.txt 'COUNTER=$(cat ~/counter.txt); echo $((COUNTER + 1)) > ~/counter.txt'

flock上記の例のように複数のコマンドを渡すにはどうすればよいですか?

私が理解している限り、flock異なるフラグ(-xは排他的、-wはタイムアウト用)、次にファイルをロックし、次にコマンドを実行します。この関数に2つのコマンドを渡す方法がわからない(ロックされたファイルの内容で変数を設定してから、このファイルをインクリメントする)。

ここでの目標は、スクリプトがcounter.txtファイルにアクセスしようとするたびにファイルをロックすることにより、ファイルに多少アトミックな増分を作成することです。

回答:


7

シェルを明示的に呼び出します。

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')

素晴らしい、どうもありがとう!あなたが提供した説明は間違いなくもう1時間の頭痛の種から私を救いました
d -_- b

4

または、ファイル記述子を群れにすることができます

exec {counterfd}<~/counter.txt
flock -x -w 5 "$counterfd"
COUNTER=$(cat ~/counter.txt)
COUNTER=$(( COUNTER +1 ))
echo "$COUNTER" >~/counter.txt
exec {counterfd}<&-

これには、サブシェルベースのアプローチとは異なり、カウンター変数を直接使用できるという利点もあります。


説明してexec {counterfd}いただけますか?それ自体ではDebianはエラーnot foundになりますが、リダイレクトでは0を返します。非常に奇妙な。
スティーブアーモンド

2

このflockツールの使い方は少しトリッキーで、manページはかなり短いです。マニュアルページには、ツールを使用する3つの方法があります。

  • flock [options] <file|directory> <command> [command args]
  • flock [options] <file|directory> -c <command>
  • flock [options] <file descriptor number>

この質問の言い方では、間違いなくの3番目の形式を使用しflockます。manページのさらに下に行くとflock、3番目の形式を使用するための正確な構文を示すいくつかの例があります。

#!/bin/bash
(
 flock -n 9 || exit 1
 echo "commands executed under lock..."
 echo "go here..."
) 9>/tmp/mylockfile

を追加しました#!/bin/bash

私はこの形式のをうまく使いましたflock

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.