proc1.sh
#!/bin/sh
touch /tmp/proc1.signature.mutex
#do something for long time
sleep 100
rm -rf /tmp/proc1.signature.mutex
proc2.sh
#!/bin/sh
touch /tmp/proc2.signature.mutex
#do something for long time
sleep 100
rm -rf /tmp/proc2.signature.mutex
proc3.sh
#!/bin/sh
touch /tmp/proc3.signature.mutex
#do something for long time
sleep 100
rm -rf /tmp/proc3.signature.mutex
コアファイル
ループまたは他の手段を使用して/tmp/proc[?][*].signature.mutex内のすべてのファイルが削除されるのを待ってから、さらに進む方法はありますか?
core.shの目標を達成する方法
答え1
ミューテックスは相互排除ロックの一種です。スクリプトprocN.sh
は、ミューテックスを「ロック」する前に他のプロセスが保持しているかどうかをテストしません。
別のスクリプトを起動すると、core.sh
そのスクリプトが完了するのを待つのは簡単です。
#!/bin/sh
./proc1.sh &
./proc2.sh &
./proc3.sh &
wait
# other processing
これにより、ファイルをロックする必要がなくなります。それが不可能な場合は検討してください。
#!/bin/sh
while [ -e "$HOME/locks/proc1.signature.mutex" ] ||
[ -e "$HOME/locks/proc2.signature.mutex" ] ||
[ -e "$HOME/locks/proc3.signature.mutex" ]
then
echo 'waiting...'
sleep 10
done
# other processing
不自然な原因が原因でスクリプトが終了してファイルが残るのを防ぐには、procN.sh
トラップを使用します。
#!/bin/sh
lockfile="$HOME/locks/proc1.signature.mutex"
while [ -e "$lockfile" ]; do
echo 'Can not get lock. Waiting...' >&2
sleep 10
done
## alternatively:
# [ -e "$lockfile" ] && { echo 'something is wrong' >&2; exit 1; }
trap 'rm "$lockfile"; exit' EXIT INT TERM HUP
touch "$lockfile"
# etc.
# no need to rm the lock file at the end
-e "$lockfile"
touch
テストとテストの間には、異なるプロセスが同じファイルに対してロックを設定できるスペースがあります。
これを防ぐには、ロックを使用してください。目次代わりに:
#!/bin/sh
lockdir="$HOME/locks/proc1.signature.mutex"
while ! mkdir "$lockdir"; do
echo 'Can not get lock. Waiting...' >&2
sleep 10
done
trap 'rmdir "$lockdir"; exit' EXIT INT TERM HUP
# etc.
# no need to rmdir the lock dir at the end
同様にシンボリックリンクを使用することもできます。
$HOME
ロックファイル/ディレクトリには以下のパスを使用しました。を使用すると、/tmp
すべてのユーザーが正しいファイル/ディレクトリを作成してスクリプトの実行をロックできます。
答え2
私は書いたhttps://github.com/acbits/semaこの理由です。長い間SEに興味を持っていないが、この問題を発見しました。 Linuxでのみテストしました。
答え3
使用https://github.com/acbits/semaシェルスクリプトでセマフォを使用します。
A.sh
_____________________________________________
#!/bin/sh
echo A.sh started
sema -c S1
./B.sh &
echo A.sh more work
echo waiting for B.sh to finish
sema -w S1
echo B.sh finished execution
echo A.sh do more work
# cleanup semaphores
sema -d S1
_____________________________________________
B.sh
_____________________________________________
#!/bin/sh
echo Hello from B.sh
sleep 5
sema -r S1
echo Bye bye from B.sh
____________________________________________