LoginSignup
43
46

シェルスクリプトでの排他処理

Last updated at Posted at 2013-03-02

業務系のシステムでシェルスクリプトを使用している場合など、 多重起動の防止などで排他制御が必要な場合が多々あると思いますが、その様な場合に役に立つシンボリックリンクを利用したシェルスクリプトでの排他制御方法です。

ただし、あくまでもシェルスクリプトによる処理ですので、厳密な意味での排他制御にはなり得ないために タイミングによってはどうしても多重起動してしまう危険性がある事は考慮しておく必要があります。

この処理では自分自身のプロセス ID をロックファイルとしてシンボリックリンクして利用しているので、排他制御を実施したプロセス ID が簡単に確認できる様にするとともに、何らかの理由で不正にロックファイルが残ってしまった場合にプロセス ID を確認する事で簡単にリカバリ可能としています。

なお、プロセス確認のために /proc を参照しているので、 Linux など /proc が存在するシステムのみで利用可能となっていますが、 ps (1) などを利用してプロセスを特定すれば /proc が無いシステムでも利用可能だと思います。
指摘によりプロセス確認の方法を汎用的な方法に変更しました。

sample
# ロックファイル
lockfile=${TMP:-/tmp}/${0##*/}

# 多重起動防止のために symbolic link を作成する
# link が作成できたら trap を設定し終了時に link を自動削除する
# synbolic link が存在しても /proc/${PID} がない場合は
# ロックファイルが不正に残っていると判断し削除して処理を続行する
while true
do
    if ln -s $$ ${lockfile} 2> /dev/null
    then
        # ロック取得できた
        break
    else
        # ロックファイルが既に存在している場合
        # ロックファイルから作成元の PID を取得する
        if kill -0 `ls -l ${lockfile} | sed 's!.* !!g'` > /dev/null 2>&1
        then
            # プロセスが存在する場合
            echo "${0##*/}: exist another instance" 1>&2
            exit 1
        else
            # プロセスが存在しない場合はロックファイルを削除してリトライ
            rm -f ${lockfile}
        fi
    fi
done

# 終わる時は必ず lockfile を削除する
trap 'rm -f ${lockfile}; exit' 0 1 2 3 11 15

# 実際の処理
    :
43
46
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
43
46