🎉

[bash]スクリプトを多重実行させないために

に公開

Motivation

  • bashスクリプトの多重実行を防止したい。
  • cron実行中かジョブ実行中かコンソール実行中か、とか深く考えたくないので、スクリプト内に仕込みたい

解決策

スクリプト上部に以下を記載

#!/bin/bash

# 多重起動防止
exec 9>"/tmp/$(basename "$0").lock"
if ! flock -n 9; then
    logger "【WARN】$0 多重起動のため、終了します"
    exit 0
fi

仕組み

  • exec 9>"/tmp/$(basename "$0").lock"
    ファイルディスクリプタ 9 を /tmp/スクリプト名.lock に紐づける。
  • flock -n 9
    そのファイルディスクリプタに対してロックを取得する。
    -n オプションにより、ロックが取れなければ待たずに即座に終了する。

これにする理由

  • crontabなどで* * * * * flock -n /tmp/hoge.lock /hoge.shと定義した場合、手動で触ってるときにcron実行とバッティングしないか気になってしまう。
  • フラグファイル管理の場合、ファイル作成コマンドと削除コマンドがスクリプト内に散りかねない。trap使いつつ序盤に処理をまとめることも可能だが、FLAG変数の定義行が必要になるため、上記の書き方のほうが手数は減らせる

注意

  • /tmp はリブートでクリアされるため、基本的には短時間で終わるスクリプトに使う
  • 複数ユーザーで実行する可能性がある場合は、ロックファイル名の工夫を

Discussion