この記事では、シェルスクリプト(bashスクリプト)で排他制御する方法を備忘録としてまとめています。
今回使用するのは flock コマンドです。
ロックが確保できない場合にタイムアウトするパターンとしないパターンの2通りに分けます。
1 タイムアウトなし
2 タイムアウトあり
1 タイムアウトなしの排他制御
#!/bin/bash
LOCKFILE=/home/ubuntu/test/flock.lock
exec {fd}> "${LOCKFILE}" # ファイルディスクリプタ作成
{
flock -x ${fd}
{
# 排他したい処理をここに書く
echo "排他制御中..."
}
flock -u ${fd}
}
echo "排他制御 終了"
例として、ファイルディスクリプタの番号を記述するテキストファイルを”/home/ubuntu/test/flock.lock”としています。
ファイルディスクリプタは exec コマンドを使用して、空いている番号を動的に採番させています。
exec {変数}> "${ファイル名}"
flockコマンドについては「help」を参照してみると下のようになっています。
この記事で使用しているのは赤字オプションのみです。
3つ使い方がありますが、1番下のファイルディスクリプタを指定する方法で排他制御をかけます。
使い方:
flock [オプション] <ファイル>|<ディレクトリ> <コマンド> [<引数>…]
flock [オプション] <ファイル>|<ディレクトリ> -c <コマンド>
flock [オプション] <ファイル記述子番号>
Manage file locks from shell scripts.
オプション:
-s, –shared 共有ロックを取得します
-x, –exclusive 排他ロックを取得します (既定値)
-u, –unlock ロックを解除します
-n, –nonblock 待機が必要な場合、失敗させるようにします
-w, –timeout <秒> 指定した時間まで待つようにします
-E, –conflict-exit-code <番号> 矛盾状態や時間切れになった場合の終了コードを指定します
-o, –close コマンドを実行する前にファイルディスクリプタを閉じるようにします
-c, –command <コマンド> シェルを介して単一のコマンドを実行します
-F, –no-fork execute command without forking
–verbose increase verbosity
-h, –help display this help
-V, –version display version
2 タイムアウトあり
#!/bin/bash
LOCKFILE=/home/ubuntu/test/flock.lock
exec {fd}> "${LOCKFILE}" # ファイルディスクリプタ作成
{
flock -w 10 -x ${fd} || {
echo "TIMEOUT"
exit 1;
}
# 排他したい処理をここに書く
echo "排他制御中..."
flock -u ${fd}
}
echo "排他制御 終了"
ロックが確保できなかった場合にタイムアウトする処理です。
コマンドオプションの -w [秒数」を指定してすることで、その秒数を超過したらタイムアウトさせてスクリプトを終了させることが可能です。(例として10秒に設定しています。)
flockコマンドで排他制御する方法については以上になります。
備忘録としてまとめましたがお役に立てればうれしいです。
コメント