2012-01-19 15 views
0

プロセスの実行が停止したかどうかを確認するルーチンを作成していて、対象となるプロセスがなくなると何かを実行します。シェルwhileループが停止していない

は、私は(私の将来のコードのテストのように)このコードを思い付いた:

#!/bin/bash 
value="aaa" 
ls | grep $value 
while [ $? = 0 ]; 
    do 
    sleep 5 
    ls | grep $value 
    echo $? 
done; 
echo DONE 

私の問題は、何らかの理由で、ループは決して停止しないということであると私は、ファイル「AAA」を削除した後、1をエコー。

Iが出力としてすぐに私は、ファイルを削除するよう「DONE」ことを期待する
0 
0 >>> I delete the file at that point (in another terminal) 
1 
1 
1 
1 
. 
. 
    . 

...

問題は何ですか?

SOLUTION:

#!/bin/bash 
value="aaa" 
ls | grep $value 
while [ $? = 0 ]; 
    do 
    sleep 5 
    ls | grep $value 
done; 
echo DONE 

答えて

6

$?の値は非常に簡単に変更されます。あなたのコードの現在のバージョンでは、この行:

echo $? 

は、前のコマンド(grep)の状態を表示します - しかし、それはechoコマンドのステータス、$? 0に設定します。

保存別の変数、コマンドを実行して、次回に上書きされることはありません1で$?の値:

#!/bin/bash 
value="aaa" 
ls | grep $value 
status=$? 
while [ $status = 0 ]; 
    do 
    sleep 5 
    ls | grep $value 
    status=$? 
    echo $status 
done; 
echo DONE 

ls | grep aaaaaaという名前のファイルが存在するかどうかを確認することを意図している場合は、この:

while [ ! -f aaa ] ; ... 

は、よりクリーンな方法です。

+0

ありがとう、これは例としてのものでした。私の最終的な命令は次のようになります: ps -ef | grep "mysqldump" | grep -v "grep mysqldump" [$? = 0]; \t do \t sleep 1200 \t ps -ef | grep "mysqldump" | grep -v "grep mysqldump"; 完了。 tar cvzf [dumpdir] [ファイル] rm [ファイル] – Rgonomike

+2

@Rgonomike: "while ps -ef | ... | grep mysqldump; do sleep 1200; done"と書くことができます。それはコードを簡素化します。 (psを構文解析するのは間違った方法ですが、mysqldumpの終了時に警告されるので、mysqldumpの親にフォローン処理をさせるのが本当に欲しいです。) –

2

$?、この場合、あなたのsleepには、最後のコマンドの戻りコードです。

+0

あなたが提案したとおりにスクリプトを編集しました(私のsleepコマンドを移動したばかりです)。それでも、同じ結果が出ても動作しません。 他の提案はありますか? – Rgonomike

+0

'$?'はあなたの 'echo'コマンドの結果です。 –

+0

確かに! OK問題が解決しました。 ありがとうございます。 – Rgonomike

1

次のようなはるかに簡単な方法で、そのループを書き換えることができます。

while [ -f aaa ]; do 
    sleep 5; 
    echo "sleeping..."; 
done 
1

あなたがテストするためのコマンドを複製するべきではありません。いつでも書くことができますあなたの場合は

 
while cmd; do ...; done 

代わりの

 
cmd 
while [ $? = 0 ]; do ...; cmd; done 

を、あなたがテストしているコマンドは、PSの出力を解析していることをコメントで言及します。あなたはそれをしてはならないという非常に良い議論があります。フォローンの処理はあなたが待っているコマンドの親によって行われるべきですが、現時点ではその問題を無視します。あなたは、単に書くことができます:それは何かと一致した 場合はgrep -vはtrueを返しますので、私は、あなたのパイプの順序を変更し

 
while ps -ef | grep -v "grep mysqldump" | 
    grep mysqldump > /dev/null; do sleep 1200; done 

注意を。この場合、私はそれが必要ではないと思うが、私はより多くの があると信じています。また、出力を破棄して、少しだけクリーンアップしました。

+1

'grep ...を避けるためのトリックがあります。 grep -v grep': 'grep '[m] ysqldump'' –

0

文字列が$valueのファイル名がローカルディレクトリに存在し、必ずしも単一のファイル名であるとは限りません。

試み:$?は、まず以下の各反復時にechoコマンドのリターンコードで満たされているので、

#!/bin/bash 
value="aaa" 
while ! ls *$value*; do 
    sleep 5 
done 
echo DONE 

あなたの元のコードに失敗しました。

今後、lsの代わりにpsをご利用になる場合は、あなたが巧妙でない限り、grepをお受け取りください。 ps -ef | grep [m]ysqlplusを使用してください。

関連する問題