2

ビルド チェーン スクリプトを作成したいのですが、コンパイル中にエラーが発生した場合、最後まで実行したくありません。

より「精巧な」スクリプトをbashで書くのは初めてですが、うまくいきません:

  1. エラーという単語が含まれる行がありますが、エラーはエコーしません
  2. testError の値がどうであれ、スクリプトはその行でハングするだけです

これはコードです:

testError=false

output=$(scons)
while read -r line; do
    if [[ $line == .*[eE]rror.* ]] ; then echo 'ERROR' ; $testError = true ; fi #$testError = true fi
done

echo $testError
if  $testError  ; then exit ; fi;

... other commands

編集:すべてのポスターの回答に従い、ループ内でグローバル変数を設定し、その値を保持する Bash -- または、ダミーの置換を処理し、bash スクリプトで正規表現を使用するにはどうすればよいですか? 、これはコードの最終バージョンです。できます:

testError=false

shopt -s lastpipe
scons | while read -r line; do
  if [[ $line =~ .*[eE]rror.* ]] ; then
    echo -e 'ERROR' 
    testError=true 
  fi 
  echo -e '.'
done

if  $testError  ; then
    set -e 
fi
4

5 に答える 5

2

testErrorパイプラインによって誘発されたサブシェルでの値を設定します。そのサブシェルが (パイプラインの最後で) 終了すると、行った変更はすべて消えます。これを試して:

while read -r line; do
   if [[ $line == .*[eE]rror.* ]] ; then
     echo -e 'ERROR' 
     testError=true 
   fi #$testError = true fi
done < <( scons )

または、プロセス置換を使用したくない、または使用できない場合は、一時ファイルを使用します

scons > tmp
while read -r line; do
  if [[ $line == .*[eE]rror.* ]] ; then
    echo -e 'ERROR' 
    testError=true 
  fi #$testError = true fi
done < tmp

これによりパイプラインが不要になるため、testErrorwhile ループの後も変更が保持されます。

また、bash のバージョンが新しい (4.2 以降) 場合は、パイプラインの最後の while ループをサブシェルではなく現在のシェルで実行できるようにするオプションがあります。

shopt -s lastpipe
scons | while read -r line; do
  if [[ $line == .*[eE]rror.* ]] ; then
    echo -e 'ERROR' 
    testError=true 
  fi #$testError = true fi
done
于 2013-02-14T00:00:54.250 に答える
1

試してみてください

set -e

これにより、コマンドがゼロ以外のステータスで終了した場合、スクリプトの続行が停止します

またはそれ以上

error_case() { # do something special; }
trap 'echo >&2 "an error occurs"; error_case' ERR

error_caseコマンドがゼロ以外のステータスで終了するたびに、この実行関数

http://mywiki.wooledge.org/BashFAQ/105を参照してください。

于 2013-02-13T23:47:03.077 に答える
1

scons の出力を解析しようとしていますか?

これ:

output=$(scons)
while read -r line; do
    if [[ $line == .*[eE]rror.* ]] ; then 
        echo 'ERROR' 
        testError=true
    fi
done

それはしません。おそらくあなたが望む:

scons | while read -r line; do ... ; done
于 2013-02-13T23:48:11.770 に答える
1

別のバグは、割り当てにスペースがあることです。そして、スキップします$

$testError = true

する必要があります

testError=true

編集

testerror はサブシェルで変更されます。試す

testerror=$(
    scons | while read -r line; do
        if [[ $line == .*[eE]rror.* ]] ; then
            echo true 
        fi #$testError = true fi
    done
)
于 2013-02-13T23:53:11.843 に答える
0

他の回答が気づかなかったので、私も回答します。正規表現の使用は、この方法で行う必要があり=~ます==

if [[ $line =~ .*[eE]rror.* ]] ; then
...

cf bashスクリプトで正規表現を使用するにはどうすればよいですか?

于 2013-02-14T00:48:10.893 に答える