次の種類のスクリプトに問題があります。
#!/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ループで終了します。
pidof
long_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
ブロックしたくない場合は、wait
bashに組み込まれているジョブ制御機能を使用してこの問題を解決します。フォークが1つしかないプロセスでは、非常に簡単に実行されます。私のアプローチは次のとおりです。
#!/bin/sh
sleep 1 &
while jobs | grep -q "Running" ; do
echo -n "." # no trailing newline
sleep 0.1
done
echo