2017-11-10 15 views
0

grepがそのパターンと一致しないときにこのループから抜け出したいと思います。ここでは、「高い」の目標は以下の通りであった。このループをbashで中断するにはどうすればいいですか?

  • は出力(stdoutが影響を受けないこと)を参照してください
  • パターン
  • 停止処理のためのgrep、それをパターンを

を見つけていないされたら。そのが働いていない理由を

#!/bin/bash 
set -ex 
i=1 
RERUN=0 
while [ ${RERUN} == 0 ] 
do 
    ((i++)) 
    echo -n "Rerun${i}"| tee >(grep --color=always 'Rerun[123]' ; export RERUN=$?) 
    echo ${RERUN} 
    sleep 1 
done 

私の推測では、それがされている別のシェルレベルで

+0

正しい: –

+0

'set -e'のためにBTW、'((i ++)) 'は実際には' i = 0'で失敗します(これは、 'set -e'が[非常に議論の余地がある] //mywiki.wooledge.org/BashFAQ/105) - アレゴリーをスキップし、急いで演習を読む)。 –

+0

...今では、プロセスの置換の終了ステータスを得ることができますが、bash 4.4を実行している場合のみ可能です。これはどんなバージョンですか? –

答えて

1

を行う必要があり、私はそうのように書くことがあります間で通信する必要がないことを

#!/bin/bash 

generate_output() { 
    local i=0 
    while :; do 
    ((++i)) 
    printf 'Rerun%s\n' "$i" 
    sleep 1 
    done 
} 

while IFS= read -r line; do 
    printf '%s\n' "$line" 
    [[ $line = Rerun[123] ]] || break 
done < <(generate_output) 

注意SIGPIPEをgenerate_outputに送るには、共有する変数を持つ2つのプロセスがあります。親にその値を変更しませんサブシェルで変数を設定し、

#!/bin/bash 
# set -x 
i=0 
RERUN_FILE=$(mktemp) 
declare -a TESTDATA=("run" "run" "run" "last" "run" "run" "run") 
while ! $(grep -q 1 ${RERUN_FILE}) 
do 
    echo -n ${TESTDATA[$i]}| tee >(grep --color=always 'run'; echo -n $? >${RERUN_FILE}) 
    ((i++)) 
    sleep 1 
done 
rm ${RERUN_FILE} # do your dishes after the meal 
+0

うーん、それとにかく、私のためにマスタードをカットしなかった。私は今解決策があると思う。 – slaxor

+0

「マスタードをカットしていない?」それは失敗ですか?特定のエラーは何ですか? –

+0

(チェックして、テストが逆転しました - 私たちが* Test1、Test2、またはTest3を見たときに*破損していました。 –

0

は私が解決策を見つけました。 `export`は値をプロセスツリーに伝播します。
+0

「しばらく! $(command-that-emits-no-output) 'が奇妙です - ' $() 'はコマンドの出力を(文字列分割とグロブ展開後の)コマンド自体として実行しますが、何もしていないので、前の終了ステータスだけが残されます。 –

+0

... btw、ループ内にパイプラインを設定する(または 'tee'や' grep'などのツールを実行する)ことは、一般的には悪い考えです。サブシェル、外部コマンド呼び出し、&c。高価です - 'grep'はシェルビルトインテスト*よりもはるかに高速ですが、起動するとコストがかかります(何度も評価しています)。 (これは一般に、外部コマンド*をあなたのループの外側に置いて、ただ1つのインスタンスから連続した行のストリームを生成し、シェル組み込み関数を使ってこれらの行を繰り返し処理することをお勧めします。 –

+0

なので、 'printf '\ n'>" $ RERUN_FILE "'を使ってsigilを設定し、 'while! 'を使った方が速いでしょう。 [-s "$ RERUN_FILE"] 'はそれが設定されるのを待つ - あなたが少なくとも1つの' grep'を避けているようにする。 (別のものとして:[POSIXが必要](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08。html)シェルと準拠のOSユーティリティーは、独自の目的のためにすべて大文字の名前を排他的に使用し、アプリケーションの使用のために小文字の名前を残します。独自のコードで小文字の変数名を使用すると意図しない競合が防止されます)。 –

関連する問題