動作しない実行インスタンスの数を計算する Bash スクリプト

動作しない実行インスタンスの数を計算する Bash スクリプト

インスタンスが私のLinuxシステムですでに実行されているかどうかを検出し、画面にインスタンス数を表示するスクリプトを作成しています。

「Detect_itself.sh」スクリプトの内容は次のとおりです。

#!/bin/sh

INSTANCES_NUMBER=`ps -ef | grep detect_itself.sh | grep -v -i grep | wc -l`
echo "Number of detect_itself.sh instances running now =" $INSTANCES_NUMBER
echo "Second method:"
ps -ef | grep detect_itself.sh | grep -v -i grep | wc -l
echo "Third method:"
echo `ps -ef | grep detect_itself.sh | grep -v -i grep | wc -l`
echo "Please, press a key"
read -r key

スクリプトを実行すると、画面に次のように表示されます。

Number of detect_itself.sh instances running now = 2
Second method:
1
Third method:
2
Please, press a key

しかし、私はそれを見せたいです:

Number of detect_itself.sh instances running now = 1
Second method:
1
Third method:
1
Please, press a key

なぜ実行するとps -ef | grep detect_itself.sh | grep -v -i grep | wc -l値1が返されるのかわかりませんが、この値を変数に保存してエコーで表示すると2が表示されます。

ベストアンサー1

これはps、サブシェルでコマンドを実行するために発生します。これを実行すると:

INSTANCES_NUMBER=`ps -ef | grep detect_itself.sh | grep -v -i grep | wc -l`

これは、コマンドを実行するために新しいサブシェルを効果的にフォークします。このフォークは親アイテムのコピーなので、2 つのdetect_itself.shインスタンスが実行中です。これを説明するには、次のコマンドを実行します。

#!/bin/sh
echo "Running the ps command directly:"
ps -ef | grep detect_itself.sh | grep -v -i grep
echo "Running the ps command in a subshell:"
echo "`ps -ef | grep detect_itself.sh | grep -v -i grep`"

以下を印刷する必要があります。

$ test.sh
Running the ps command directly:
terdon   25683 24478  0 14:58 pts/11   00:00:00 /bin/sh /home/terdon/scripts/detect_itself.sh
Running the ps command in a subshell:
terdon   25683 24478  0 14:58 pts/11   00:00:00 /bin/sh /home/terdon/scripts/detect_itself.sh
terdon   25688 25683  0 14:58 pts/11   00:00:00 /bin/sh /home/terdon/scripts/detect_itself.sh

幸いにもこれを行うアプリがあります!こういうことがまさにpgrep存在する理由だ。したがって、スクリプトを次のように変更します。

#!/bin/sh
instances=`pgrep -fc detect_itself.sh`
echo "Number of detect_itself.sh instances running now = $instances"
echo "Second method:"
ps -ef | grep detect_itself.sh | grep -v -i grep | wc -l
echo "Third method (wrong):"
echo `ps -ef | grep detect_itself.sh | grep -v -i grep | wc -l`

以下を印刷する必要があります。

$ detect_itself.sh
Number of detect_itself.sh instances running now = 1
Second method:
1
Third method (wrong):
2

重要:これは安全ではありません。たとえば、というスクリプトがある場合、そのthis_will_detect_itselfスクリプトが計算されます。テキストエディタでファイルを開くと、そのファイルも計算されます。この種の作業のより安定した方法は、ロックファイルを使用することです。それは次のとおりです。

#!/bin/sh

if [[ -e /tmp/I_am_running ]]; then
    echo "Already running! Will exit."
    exit
else
    touch /tmp/I_am_running
fi
## do whatever you want to do here

## remove the lock file at the end
rm /tmp/I_am_running

あるいは、より良い方法は、スクリプトがtrapクラッシュしてもファイルを削除するために使用することを検討することです。詳細は、正確に実行したいタスクと実行中のインスタンスをインスツルメントする必要がある理由によって異なります。

おすすめ記事