シェルでスクリプトの多重起動を制御する方法とサンプルコードを紹介します。cronでスクリプトを実行して処理が終わらないまま、次の実行時刻になってしまうことのないように。
サンプルコード
- スクリプト
#!/bin/bash
# ロックファイル/ログファイル
LOG_FILE=/path/`date +\%Y\%m\%d`.log
LOCK_FILE=/path/file.lock
# ロックファイルの確認と作成
if ! ln -s $$ ${LOCK_FILE}; then
echo "LOCKED"
exit
fi
# 実行開始時間をログに残す
echo "実行開始 : "`date` >>${LOG_FILE} 2>&1
########################################
# Main実行
########################################
/bin/bash /path/main.sh >>${LOG_FILE} 2>&1
# エラーチェック
if [ $? -ne 0 ]; then
echo "実行コマンドエラー" >>${LOG_FILE} 2>&1
fi
# 実行終了時間をログに残す
echo "実行終了 : "`date` >>${LOG_FILE} 2>&1
# ロックファイルの削除
rm ${LOCK_FILE}
exit
- ログ
実行開始 : Thu May 2 17:31:01 JST 2019
実行終了 : Thu May 2 17:39:47 JST 2019
実行開始 : Thu May 2 17:46:01 JST 2019
実行終了 : Thu May 2 17:54:44 JST 2019
実行開始 : Thu May 2 18:01:01 JST 2019
実行終了 : Thu May 2 18:09:48 JST 2019
実行開始 : Thu May 2 18:16:01 JST 2019
実行終了 : Thu May 2 18:24:46 JST 2019
実行開始 : Thu May 2 18:31:01 JST 2019
スポンサードサーチ
備忘録
6分で終わるスクリプトを15分間隔で動かしてます。もしデータ量が急に増えてスクリプト実行時間が15分を超えてしまっても次の15分後に実行されます。
ロックファイルの生成はシンボリックリンクで
「ロックファイル確認」→「ロックファイル作成」という処理だと、ロックファイル「確認」と「作成」の間に処理が走ってしまう可能性があり、完全にロックされている状態ではありません。下記はNGです。
# ファイルの存在チェック
if [ -e ファイル ]; then
# ロック!
exit
fi
# ロックファイル作成
touch ${LOCK_FILE}
「ロックファイル確認」と「ロックファイル作成」は同時に行う必要があります。シンボリックリンクでロックファイルを生成すると、既にファイルが存在するとエラーになり処理が中断され、ファイルがなかった場合はロックファイルが生成されます。
# ロックファイルの確認と作成
if ! ln -s $$ ${LOCK_FILE}; then
echo "LOCKED"
exit
fi
補足
# ログのローテートも忘れずに!
0 1 * * * /logrotate.sh
#!/bin/bash
# log roteta everyday
# ログファイルのある場所へ移動
cd /log/path/
# ログが30日以上あるものを抽出して削除
find ./ -name '*.log' -mtime +30 -exec rm -f {} \;