bashスクリプトのインスタンスを1つだけ実行させる方法は?

bashスクリプトのインスタンスを1つだけ実行させる方法は?

追加のツールを必要としないソリューションが推奨されます。

答え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

関連情報