複数のBashシェルスクリプトを並列に実行したいと思います。しかし、競争条件を避けたい。 Unixコマンドとは何ですか?本当にこの目的のためにどの原子を使用でき、どのように使用しますか?
答え1
#!/bin/bash
# Makes sure we exit if flock fails.
set -e
(
# Wait for lock on /var/lock/.myscript.exclusivelock (fd 200) for 10 seconds
flock -x -w 10 200
# Do stuff
) 200>/var/lock/.myscript.exclusivelock
これにより、「(」と「)」の間のコードは一度に1つのプロセスによってのみ実行され、そのプロセスが長すぎるロックを待たないようになります。
答え2
lockfile
これはシステムにインストールされていない場合に行われmkdir
ます。これはアトミック操作なので、ディレクトリが-p
すでに存在する場合は失敗します(コマンドラインスイッチを追加しない限り)。
create_lock_or_wait () {
path="$1"
wait_time="${2:-10}"
while true; do
if mkdir "${path}.lock.d"; then
break;
fi
sleep $wait_time
done
}
remove_lock () {
path="$1"
rmdir "${path}.lock.d"
}
答え3
lockfile(1) は良い候補のように見えますが、プログラムメールコンピュータにインストールされていない可能性があるパッケージです。まだインストールしていない場合は、システムに合わせてパッケージする必要があるほど人気のあるパッケージです。私が確認した4つのシステムのうち、3つのシステムにこの機能があり、1つのシステムには使用できました。
それを使用するのは簡単です:
#!/bin/sh
LOCKFILE=$HOME/.myscript/lock
mkdir -p `dirname $LOCKFILE`
echo Waiting for lock $LOCKFILE...
if lockfile -1 -r15 $LOCKFILE
then
# Do protected stuff here
echo Doing protected stuff...
# Then, afterward, clean up so another instance of this script can run
rm -f $LOCKFILE
else
echo "Failed to acquire lock! lockfile(1) returned $?"
exit 1
fi
私が提供したオプションは、最大15秒間毎秒再試行します。永久に待つには、「-r」フラグを削除します。
答え4
たぶん、lockfileコマンドはあなたのニーズに合うかもしれません。
lockfile ~/.config/mylockfile.lock
.....
rm -f important.lock