2016-06-19 9 views
2

特定のプロセスが完了するまで進捗インジケータを表示できましたが、実行中に同じ進捗インジケータを表示するコードを取得できませんでした。ループ。私は、スクリプト内でsleepコマンドを使用して進捗状況を表示することができBashスクリプト:whileループが完了するまで進捗インジケータを表示

/bin/ping -c 10 $ipaddress > /pinglog & PID=$! 
printf "[" 
while kill -0 $PID 2> /dev/null; do 
    printf "." 
    sleep 1 
done 
printf "] " 

sleep 30 & PID=$! 
printf "[" 
while kill -0 $PID 2> /dev/null; do 
printf "." 
sleep 1 
done 
printf "] " 

これらの例のいずれもが仕事と私の出力がどのように見える私は、スクリプト内でpingを実行する場合たとえば、私はこれを行いますこれは:

[.........................} 

コマンドが完了するまでドットが1秒間続きますが、これは私が望むものです。しかし、私は今、whileループを使って同じ出力を得ようとしています。私は後の結果を得ることができません。ここまで私がこれまで持っていたことがあります。

while [[ ! $(/bin/grep -wo -m1 $VAR1 /logfile) ]] & PID=$! 
printf "[" 
while kill -0 $PID 2> /dev/null; do 
    printf "." 
    sleep 1 
done 
printf "] " 
do 
sleep 5 
done 
echo $VAR1 was found 

これは、文字列が見つかったとき、それは停止しませんが実行され、出力は次のようになります。

[.] [.] [.] [.] [.] and on and on... 

私はループを行う一方で、実際の移動しようとした、睡眠5と第1の上に行っていますprintfステートメントを実行しても結果は悪く、進捗インジケーター出力も表示されません。最初の2つの例が私に与えているのと同じ進捗インジケータの出力を得るために、これを修正できますか?パターンが見つかると停止しますか?

答えて

0

私はこの問題を解決しました。 [........]出力フォーマットを使用するには、最初のprintf "["を最初のwhileループが始まる前に開始する必要があります。次にsleep 5コマンドをバックグラウンドに置き、whileループ自体ではなくsleepの5コマンドを強制終了したいので、最初のwhileループではなく、PIDの2番目のwhileループを使用します。これにより、5秒ごとではなく、1秒ごとに角カッコ内でドットを繰り返すことができ、検索文字列を見つけることができます。最後に最後のprintf "]"を最後のdoneの外側に置いて、検索文字列のwhileループの終了後に書式設定を完了します。これは、5秒ごとに繰り返される[。]を防ぎます。これは私のために働いた:

printf "[" 
while [[ ! $(/bin/grep -wo -m1 $VAR1 /logfile) ]] 
do 
sleep 5 & PID=$! 
while kill -0 $PID 2> /dev/null; do 
    printf "." 
    sleep 1 
done 
done 
printf "] " 
echo $VAR1 was found 
1

whileでテストされたコマンドは、doより前の最後のコマンドです。したがって、ループは基本的にwhile ...; printf "] "; do ... ; endであり、printfは決して失敗しないため、whileは決して終了しません。

whileループでテストすると思われる内容はわかりませんが、コンパウンドコマンド[[ ! $(/bin/grep -wo -m1 $VAR1 /logfile) ]] &がテストされることが期待される場合は、バックグラウンドでコマンドを実行するとき、ステータスコードは、背景コマンドを実行するためにbashが子をフォークできるかどうかを反映するだけですほとんどの場合)。コマンドのステータスコードは、コマンドが完了するまで利用できませんので、状況コードを確認するだけであれば、バックグラウンドで実行するのは無意味です。

whileループ全体をバックグラウンドで処理することができます。 &doneの後ろに置き、while複合ステートメントを終了します。

printf "[" 
while ! grep -wqm1 "$VAR1" logfile; do 
    sleep 1 
done & 
while kill -0 $! 2>/dev/null; do 
    printf "." 
done 
printf "] " 

注:それはあなたが実際に探しているものはおそらくだgrepから-qオプションは、それだけでステータスリターンを生成する原因となります。 (その変更により、実際には-m1は冗長です)。出力をテストするために[[を使用する必要がありません。 $VAR1に空白またはメタ文字を含めることができないことが100%保証されている場合を除き、展開を引用符で囲む必要があります。変数には$!を格納する必要はありません。これは、他のコマンドをバックグラウンドにするまで同じ値を継続して保持するためです。

+0

whileループを使用して特定のログファイルにパターンが存在するかどうかをテストします。パターンが表示されるのを待つ間に、最初の2つの例で示したように、進行中のインジケータを表示し、別のwhileループを使用します。ネストされたループが話すように。パターンが現れると、printf [......]は停止するはずです。 – user53029

+0

あなたが言ったことをちょうど読み返してください。しかし、printfは、最初のwhileループのPIDが終了したとき(パターンが見つかったとき)に、失敗するか、完了するか、何かをする必要があります。しかし、それはしません。少なくともこのコードではありません。 – user53029

+0

@ user53029: 'printf'は失敗しません。それはなぜでしょうか? – rici

関連する問題