アドバイザリ ロックは古くから使用されており、bash スクリプトで使用できます。シンプルな flock
が好き (util-linux[-ng]
から) ) lockfile
以上 (procmail
より) )。そして、終了時のトラップについて常に覚えておいてください (sigspec ==EXIT
または 0
、これらのスクリプトでは、特定のシグナルをトラップすることは不要です)。
2009 年に、ロック可能なスクリプトのボイラープレートをリリースしました (当初は私の wiki ページで入手できましたが、現在は gist として入手できます)。これをユーザーごとに 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.
スクリプトがすべてのユーザーで同じである場合は、 lockfile
を使用できます アプローチ。ロックを取得した場合は続行し、それ以外の場合はメッセージを表示して終了します。
例:
[Terminal #1] $ lockfile -r 0 /tmp/the.lock
[Terminal #1] $
[Terminal #2] $ lockfile -r 0 /tmp/the.lock
[Terminal #2] lockfile: Sorry, giving up on "/tmp/the.lock"
[Terminal #1] $ rm -f /tmp/the.lock
[Terminal #1] $
[Terminal #2] $ lockfile -r 0 /tmp/the.lock
[Terminal #2] $
/tmp/the.lock
以降 取得されたスクリプトは、実行にアクセスできる唯一のスクリプトになります。完了したら、ロックを外すだけです。スクリプト形式では、これは次のようになります:
#!/bin/bash
lockfile -r 0 /tmp/the.lock || exit 1
# Do stuff here
rm -f /tmp/the.lock
flock
だと思います おそらく最も簡単な (そして最も記憶に残る) バリアントです。 cron ジョブで使用して、DVD と CD を自動エンコードします
# try to run a command, but fail immediately if it's already running
flock -n /var/lock/myjob.lock my_bash_command
-w
を使用 タイムアウトの場合、またはロックが解除されるまで待機するオプションを除外します。最後に、man ページには複数のコマンドの良い例が示されています:
(
flock -n 9 || exit 1
# ... commands executed under lock ...
) 9>/var/lock/mylockfile