同じUnixスクリプトを実行する前に、スクリプトの古いインスタンスを終了してください。

同じUnixスクリプトを実行する前に、スクリプトの古いインスタンスを終了してください。

再実行したいシェルスクリプトに属するバックグラウンドプロセスを終了したいと思います。

これは、シェルスクリプトを実行する前に実行中のバックグラウンドプロセスを削除したいことを意味します。同じスクリプト。

答え1

同じスクリプトにPIDが存在することを確認してください。

スクリプトの先頭に以下を追加します。

#!/bin/bash
script_name=${BASH_SOURCE[0]}
for pid in $(pidof -x $script_name); do
    if [ $pid != $$ ]; then
        kill -9 $pid
    fi 
done

答え2

kill -9 $(pgrep -f ${BASH_SOURCE[0]} | grep -v $$)

とても簡単です。
現在実行中のスクリプトのすべてのインスタンスを取得するには、pgrepを使用します。

pgrep は pid だけを返すので良いです。

その後、$$を使用して現在実行中のpidを特定して、自己終了を防ぎます。

最後に、kill -9 は古いインスタンスを終了します。

答え3

私はずっと前に私のシェルスクリプトの1つでこれをしました。これが私がする方法です:

ps aux | \
grep -P ${BASH_SOURCE[0]} | \
grep -v $$ | \
grep -P "bash" | \
grep -oP "^[[:alnum:]]+\s+\d+\s" | \
grep -oP "\d+" | \
xargs kill -9

この方法の利点は、現在実行中のスクリプト自体を終了せずに古いインスタンスのみを終了することです。

上記のアプローチを示すサンプルスクリプトは次のとおりです。

#!/bin/bash

ps aux | grep -P ${BASH_SOURCE[0]} | grep -v $$ | grep -P "bash" | grep -oP "^[[:alnum:]]+\s+\d+\s" | grep -oP "\d+"

sleep 100

次に、端末でこのスクリプトのインスタンスを実行します。次に、別の端末で別のインスタンスを実行します。前のインスタンスはすぐに終了し、2番目のインスタンスは正常に実行されていることがわかります。

答え4

$0代わりに使用できます${BASH_SOURCE[0]}

何らかの理由で後者が何も返さなかったので、代わりにpgrep -f <filename>使用する必要がありました。pidof -x <filename>

また、kill -9ここでは必要ありません。

したがって、結果は次のようになります(@jcbermyの答えからインスピレーションを得ます)。

#!/bin/bash
for pid in $(pgrep -f $0); do
    if [ $pid != $$ ]; then
        kill $pid
    fi 
done

関連情報