初めに #
Linuxにてシステムを運用している環境では「同じ処理が同時に動いてしまった」「前のジョブが終わる前に次が走ってしまった」といったトラブルに出くわすことがあります。
こうした多重実行や競合を防ぐのに便利なのが、flockコマンドによるファイルロックとなります。
そこで本記事では、AlmaLinuxを例に、flockコマンドの基本的な使い方について初心者向けにわかりやすく解説します。
flockコマンドとは #
flock
コマンドは、ファイルを利用し排他制御(ロック)を行うためのLinuxコマンドとなります。
複数のプロセスやスクリプトが同時に同じファイルや処理を扱うのを防ぎ、「同時実行による競合」や「データの書き換えミス」を防止することが可能です。
指定したファイルに「ロック(鍵)」をかけ、他のプロセスが同じロックを取得しようとすると待機または失敗させることで、一度に一つの処理だけが実行されるように制御する仕組みとなっています。
例として以下のようなケースで利用される事がございます。
- Cronジョブが重複して実行されるのを防ぎたい
- 同じスクリプトを複数ユーザーが同時に起動しないようにしたい
- 一時ファイルやログファイルへの同時書き込みを防ぎたい
利用確認 #
AlmaLinuxをはじめとするRHEL系ディストリビューションでは、util-linuxパッケージに含まれており、特別なインストールを行う事なく利用が可能となっております。
Linux環境で flock
コマンドが利用可能かどうかは、以下のようにwhich
コマンドで確認する事ができます。
$ which flock
/usr/bin/flock
基本的な利用方法 #
flockコマンドの基本書式は以下の通りとなっております。
flock [オプション] <ロックファイルパス> <実行するコマンド>
例えば、 /tmp/mylock.lock
というロックファイルを用いて test-script.sh
の多重起動を防止する場合は次のように実行します。
flock -n /tmp/mylock.lock bash test-script.sh
この例では、指定したロックファイルを取得できた場合にのみスクリプトを実行するといった処理となります。
スクリプトの実行中は、そのロックファイルに対してロックが保持され、他のプロセスは同じロックを取得できなくなります。
また、スクリプトの実行が完了すると、flock
は自動的にロックを解除します。
もしすでに別のプロセスが /tmp/mylock.lock
をロック中であれば、-n
オプションの指定により終了となります。
コマンドのオプション #
flock
コマンドのオプションは以下の通りとなっております。
オプション | 説明 |
---|---|
-x , --exclusive |
排他ロックを取得します(デフォルト動作)。他のプロセスが同じファイルをロックできなくなります。 |
-s , --shared |
共有ロックを取得します。複数のプロセスが同時に読み込み専用でアクセスする場合に使用します。 |
-u , --unlock |
指定したロックを解除します。通常はスクリプト終了時に自動で解除されます。 |
-n , --nonblock |
ロックを取得できない場合、処理を終了します(非ブロッキングモード)。 |
-w <秒> , --timeout <秒> |
ロックを取得できないとき、指定した秒数だけ待機します。時間内に取得できなければ終了します。 |
-E <番号> , --conflict-exit-code <番号> |
ロックの競合やタイムアウトが発生したときに返す終了コードを指定します。 |
-o , --close |
コマンドを実行する前に、ファイルディスクリプタを閉じるようにします。特殊な用途向けです。 |
-c <コマンド> , --command <コマンド> |
シェルを介して1行でコマンドを実行します。flock -c "echo test" のように使えます。 |
-F , --no-fork |
コマンドをフォークせずに実行します。プロセス管理が必要な場合に利用します。 |
--verbose |
実行時に詳細なメッセージを表示します。デバッグ時に便利です。 |
-h , --help |
flock のヘルプメッセージを表示します。 |
-V , --version |
flock のバージョン情報を表示します。 |
flock で利用できるロックには、排他ロック(-x
) と 共有ロック(-s
)の2種類が存在します。
排他ロックは、指定対象となるファイルや処理に対して、一度に一つのプロセスしかアクセスできないようにするロックとなります。
読み込みも書き込みも、他のプロセスが同時に行うことはできません。
一方で共有ロックは、読み込み専用の処理に対して複数のプロセスが同時にアクセスできるロックとなります。
そのため読み込み自体は複数プロセスで同時に行えますが、書き込みは実行できません。
以下は各ロックの比較となっております。
ロック種類 | 読み込み | 書き込み |
---|---|---|
排他ロック (-x ) |
一度に1プロセスのみ利用可能 | 一度に1プロセスのみ利用可能 |
共有ロック (-s ) |
複数プロセスが利用可能 | 利用不可 |
実際の使用例 #
では実際に flock
コマンドを利用しスクリプトの二重実行を防ぐ流れを、簡単な例をもとに解説します。
1. テスト用スクリプトの準備 #
初めに、確認に利用する簡単なスクリプトを作成します。
今回は例として test-script.sh
として保存しました。
このスクリプトは10秒間スリープし、時刻を表示する処理となっております。
#!/bin/bash
echo "スクリプト開始: $(date)"
sleep 10
echo "スクリプト完了: $(date)"
2. flock を使ってコマンドラインから実行 #
次に、作成したスクリプトを 意図的に二重実行 し、flock
によって競合が回避されるかを確認してみます。
今回は ターミナルA と ターミナルB の2つのターミナルを用意し、ほぼ同時に以下のコマンドを実行しました。
flock -n ./test.lock ./test-script.sh || echo "他のプロセスが実行中のためスクリプトは実行されませんでした"
3. 結果 #
先ほどの手順で、ターミナルAとターミナルBから同時にスクリプトを実行した結果は以下の通りです。
ターミナルAではスクリプトが問題なく実行される一方でターミナルBではロックを取得できなかったため、スクリプトは実行されませんでした。
この結果から、flock
を使用すると、先に実行されたプロセスがロックを保持している間は、他のプロセスが同じスクリプトを実行できない事が確認できます。
ターミナルAでの実行 #
flock -n ./test.lock ./test-script.sh || echo "他のプロセスが実行中のためスクリプトは実行されませんでした"
スクリプト開始: 2025年 10月 5日 日曜日 16:48:36 JST
スクリプト完了: 2025年 10月 5日 日曜日 16:48:46 JST
ターミナルBでの実行 #
$ flock -n ./test.lock ./test-script.sh || echo "他のプロセスが実行中のためスクリプトは実行されませんでした"
他のプロセスが実行中のためスクリプトは実行されませんでした