2012/06/21

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

業務系のシステムでシェルスクリプトを使用している場合など、 多重起動の防止などで排他制御が必要な場合が多々ある。
その様な場合に役に立つ(と思われる) シンボリックリンクを利用したシェルスクリプトでの排他制御方法。
ただし、あくまでもシェルスクリプトによる処理なので、 厳密な意味での排他制御にはなり得ないために タイミングによってはどうしても多重起動してしまう危険性がある事は 考慮しておく必要がある。

この処理では自分自身のプロセス ID をロックファイルとして シンボリックリンクして利用しているので、 排他制御を実施したプロセス ID が簡単に確認できる様にするとともに、 何らかの理由で不正にロックファイルが残ってしまった場合に プロセス ID を確認する事で簡単にリカバリ可能としている。
なお、プロセス確認のために /proc を参照しているので、 Linux など /proc が存在する システムのみで利用可能となっているが、 ps (1) などを利用してプロセスを特定すれば /proc が無いシステムでも利用可能だろう。

  1# ロックファイル
  2lockfile=${TMP:-/tmp}/${0##*/}
  3
  4# 多重起動防止のために symbolic link を作成する
  5# link が作成できたら trap を設定し終了時に link を自動削除する
  6# synbolic link が存在しても /proc/${PID} がない場合は
  7# ロックファイルが不正に残っているので削除して処理を続行する
  8while true
  9do
 10    if ln -s $$ ${lockfile} 2> /dev/null
 11    then
 12        # ロック取得できた
 13        break
 14    else
 15        # ロックファイルが既に存在している場合
 16        # ロックファイルから作成元の PID を取得する
 17        if [ -d /proc/`ls -l ${lockfile} | sed 's!.* !!g'` ]
 18        then
 19            # プロセスが存在する場合
 20            echo "${0##*/}: exist another instance" 1>&2
 21            exit 1
 22        else
 23            # プロセスが存在しない場合はロックファイルを削除してリトライ
 24            rm -f ${lockfile}
 25        fi
 26    fi
 27done
 28
 29# 終わる時は必ず lockfile を削除する
 30trap 'rm -f ${lockfile}; exit' 0 1 2 3 11 15
 31
 32# 実際の処理
 33    :
    


Copyright © Mitzyuki IMAIZUMI 2008,2009. All rights reserved.