追加のツールを必要としないソリューションが推奨されます。
答え1
nsgの答えとほぼ同じです。ロックを使用してください。目次。ディレクトリの作成は、linux、unix、* BSD、その他多くのオペレーティングシステムでアトミックに行われます。
if mkdir -- "$LOCKDIR"
then
# Do important, exclusive stuff
if rmdir -- "$LOCKDIR"
then
echo "Victory is mine"
else
echo "Could not remove lock dir" >&2
fi
else
# Handle error condition
...
fi
デバッグ目的でロックshのPIDをロックディレクトリ内のファイルに入れることができますが、PIDをチェックしてロックプロセスがまだ実行中であることを確認できると考えるトラップに陥らないでください。そのプロセスには多くの競争条件があります。
答え2
追加するブルース・エディガーの回答、そしてインスピレーションを受けてこの回答、スクリプトが終了しないようにするには、クリーンアップにインテリジェンスを追加する必要があります。
#Remove the lock directory
cleanup() {
if rmdir -- "$LOCKDIR"; then
echo "Finished"
else
echo >&2 "Failed to remove lock directory '$LOCKDIR'"
exit 1
fi
}
if mkdir -- "$LOCKDIR"; then
#Ensure that if we "grabbed a lock", we release it
#Works for SIGTERM and SIGINT(Ctrl-C) as well in some shells
#including bash.
trap "cleanup" EXIT
echo "Acquired lock, running"
# Processing starts here
else
echo >&2 "Could not create lock directory '$LOCKDIR'"
exit 1
fi
答え3
bashスクリプトの単一インスタンスが実行されていることを確認する別の方法は次のとおりです。
#! /bin/bash -
# Check if another instance of script is running
if pidof -o %PPID -x -- "$0" >/dev/null; then
printf >&2 '%s\n' "ERROR: Script $0 already running"
exit 1
fi
...
pidof -o %PPID -x -- "$0"
既存のスクリプトがすでに実行されている場合はそのPIDを取得し、他のスクリプトが実行されていない場合はエラーコード1で終了します。
¹まあ、同じ名前のプロセスはすべて...
答え4
簡単すぎる場合がありますので、間違っている場合は訂正してください。十分簡単ではありませんかps
?
#!/bin/bash
me="$(basename "$0")";
running=$(ps h -C "$me" | grep -wv $$ | wc -l);
[[ $running > 1 ]] && exit;
# do stuff below this comment