バックグラウンドスクリプトが存在するかどうかを正しくポーリングする方法

バックグラウンドスクリプトが存在するかどうかを正しくポーリングする方法

次の種類のスクリプトに問題があります。

  #!/bin/sh

  long_running_script.sh &  

  while [ `pidof long_running_script.sh` ]
  do
    echo "."
    sleep 1
  done

このスクリプトは、バックグラウンドで新しいスクリプトを起動し、バックグラウンドスクリプトが終了するまでポイントを印刷する必要があります。 CPU負荷が高くない場合に動作します。

ただし、CPU負荷が高いと動作しません。 long_running_script.shが開始されますが、「親」スクリプトはlong_running_script.shが終了する前にwhileループで終了します。

pidoflong_running_script.shが実際に起動(実行)される前に実行されているようです。

この問題を解決するための最良の方法は何ですか?

whileステートメントが出る前に1秒間寝るのは役に立ちません。したがって、信頼できない魔法の遅延を使用したくありません。

答え1

pidofプロセス名の最初の部分(argv[0])のみを確認するため、スクリプトが見つかりません。

使用できますが、pidof -mこれは次のものを見つけるでしょうどの long_running_script.sh、このスクリプトで始まったわけではありません。

$!より良いアプローチは、最新のバックグラウンドジョブのPIDを保持する変数を使用することです。

#!/bin/bash

long_running_script.sh &  
pid=$!

while ps -p $pid >/dev/null
do
    echo "."
    sleep 1
done

答え2

ブロックしたくない場合は、waitbashに組み込まれているジョブ制御機能を使用してこの問題を解決します。フォークが1つしかないプロセスでは、非常に簡単に実行されます。私のアプローチは次のとおりです。

#!/bin/sh

sleep 1 &

while jobs | grep -q "Running" ; do
    echo -n "."     # no trailing newline
    sleep 0.1
done

echo 

答え3

使用wait:

#!/bin/sh
  long_running_script.sh &  
  wait
  echo "done"

詳しくは

関連情報