Linux 上の Bash の場合、特定のスクリプトのインスタンスが 1 つだけ実行されるようにする最も簡単/最善の方法は何ですか?
現時点では、次のことを行っています:
ps -C script.name.sh > /dev/null 2>&1 || ./script.name.sh
しかし、いくつか問題があります。
- チェックをスクリプトの外側に置く
- 別々のアカウントから同じスクリプトを実行することはできませんが、それが可能な場合が時々あります。
-C
プロセス名の最初の14文字のみをチェックします
もちろん、独自の pidfile 処理を記述することもできますが、それを実行する簡単な方法があるはずだと感じています。
ベストアンサー1
アドバイザリ ロックは長年使用されており、bash スクリプトでも使用できます。私は(flock
からutil-linux[-ng]
) よりも単純なlockfile
( から) を好みます。また、これらのスクリプトでは終了時のトラップ (sigspec ==または、特定のシグナルをトラップするのは不要)procmail
について常に覚えておいてください。EXIT
0
2009年に私はロック可能なスクリプト定型文をリリースしました(当初は私のWikiページで公開されていましたが、現在は要旨)。これをユーザーごとに 1 つのインスタンスに変換するのは簡単です。これを使用すると、ロックや同期を必要とする他のシナリオ用のスクリプトも簡単に作成できます。
便宜上、ここに定型文を記載します。
#!/bin/bash
# SPDX-License-Identifier: MIT
## Copyright (C) 2009 Przemyslaw Pawelczyk <[email protected]>
##
## This script is licensed under the terms of the MIT license.
## https://opensource.org/licenses/MIT
#
# Lockable script boilerplate
### HEADER ###
LOCKFILE="/var/lock/`basename $0`"
LOCKFD=99
# PRIVATE
_lock() { flock -$1 $LOCKFD; }
_no_more_locking() { _lock u; _lock xn && rm -f $LOCKFILE; }
_prepare_locking() { eval "exec $LOCKFD>\"$LOCKFILE\""; trap _no_more_locking EXIT; }
# ON START
_prepare_locking
# PUBLIC
exlock_now() { _lock xn; } # obtain an exclusive lock immediately or fail
exlock() { _lock x; } # obtain an exclusive lock
shlock() { _lock s; } # obtain a shared lock
unlock() { _lock u; } # drop a lock
### BEGIN OF SCRIPT ###
# Simplest example is avoiding running multiple instances of script.
exlock_now || exit 1
# Remember! Lock file is removed when one of the scripts exits and it is
# the only script holding the lock or lock is not acquired at all.