サイトアイコン ex1-lab

【Linux】シェルスクリプトの2重起動を防ぐ方法(flock編)

centos_logo

centos_logo

Cronなどで定期的にスクリプトを実行していると、前回の処理が終わらないうちに次が起動してスクリプト等が2重起動してそれが原因でリソースが多く使いサーバーが不安定になったりするケースがあります

このようにCronでスクリプトを実行する場合に、2重起動を防止する機能を追加したシェルスクリプトにする方法を紹介します

今回は、Linuxで標準的に使える flock を使って、簡単に2重起動を防止する方法をご紹介します。

flock とは?

flock は ファイル単位で排他制御(ロック)を行うためのコマンドです。主にスクリプトやプロセスの同時実行制御に使われます。

flock のインストール

多くのLinuxディストリビューション(CentOS, Rocky Linux, Ubuntuなど)には標準で flock が含まれています。flockがない場合は以下でインストールできます:

・RHEL系(CentOS / Rocky Linux)

$ sudo yum install util-linux

・Debian系(Ubuntuなど)

$ sudo apt install util-linux

スクリプトの2重起動を防ぐ

以下は、/tmp/test.lock というロックファイルを使って、同じスクリプトが複数同時に実行されるのを防ぐサンプルです

#!/bin/bash

LOCKFILE="/tmp/test.lock"

# ファイルディスクリプタ200を使ってロックを取得
exec 200>"$LOCKFILE"
flock -n 200 || {
    echo "[$(date '+%F %T')] Another instance is already running. Exiting."
    exit 1
}

echo "[$(date '+%F %T')] Script started."

# ★ここに本処理を書く
sleep 60  # テスト用に1分だけ待機

echo "[$(date '+%F %T')] Script finished."

サンプルのシェルスクリプトの詳細

exec 200>”$LOCKFILE”ファイルディスクリプタ200でロックファイルをオープン
flock -n 200ロックを試みる(-n は「待機しない」)
exit 1他プロセスが実行中なら即終了
sleep 60実際の処理の代わりに1分待機(例)

ロックの解除は不要?

スクリプト終了時にファイルディスクリプタ200が自動的に閉じられるため、ロックも自動で解除されます。
明示的に flock -u などを記述する必要はありません。

ログファイルに記録する

シェルスクリプトの処理内容をログに残したい場合は、以下のようにしてログを記録するようにします

#!/bin/bash

LOGFILE="/var/log/test_script.log"

exec 200>/tmp/test.lock
flock -n 200 || {
    echo "$(date '+%F %T') - Already running." >> "$LOGFILE"
    exit 1
}

echo "$(date '+%F %T') - Started." >> "$LOGFILE"
# 実処理…
echo "$(date '+%F %T') - Finished." >> "$LOGFILE"

まとめ

モバイルバージョンを終了