0

ループを書き込もうとしていますが、うまくいきません:

for t in `ls $TESTS_PATH1/cmd*.in` ; do
  diff $t.out <($parser_test `cat $t`)
  # Print result
  if [[ $? -eq 0 ]] ; then
    printf "$t ** TEST PASSED **"
  else
    printf "$t ** TEST FAILED **"
  fi
done

これも役に立ちません:

$parser_test `cat $t` | $DIFF $t.out -

Diff は、出力が異なることを示しています (奇妙です。必要なエラー行の出力が標準出力に出力され、diff によってキャッチされないため) が、一時ファイルを使用して実行すると、すべて正常に動作します。

for t in `ls $TESTS_PATH1/cmd*.in` ; do
  # Compare output with template
  $parser_test `cat $t` 1> $TMP_FILE 2> $TMP_FILE
  diff $TMP_FILE $t.out
  # Print result
  if [[ $? -eq 0 ]] ; then
      printf "$t $CGREEN** TEST PASSED **$CBLACK"
  else
      printf "$t $CRED** TEST FAILED **$CBLACK"
  fi
done

一時ファイルの使用は避けなければなりません。最初のループが機能しない理由とその修正方法 ありがとうございました。

PS ファイル *.in には、プログラムの誤ったコマンド ライン パラメータが含まれており、*.out には、プログラムがこれらのパラメータに対して出力する必要があるエラー メッセージが含まれています。

4

2 に答える 2

4

まず、エラーに、標準エラーをリダイレクトする必要があります。

diff $t.out <($parser_test `cat $t` 2>&1)

第二に、あなたが気づいていないかもしれない他のすべての問題に:

  • lsループで使用しないでforください (スペースを含むファイル名での予期しない動作など、多くの問題があります)。代わりに、次を使用します。for t in $TESTS_PATH1/cmd*.in; do
  • スペースを含むファイル名をサポートするには、変数展開を引用符で囲みます:"$t"の代わりに$t
  • 逆引用符を使用しないでください。それらは推奨されていません$(command)
  • サブシェルを使用して 1 つのファイルを cat しないでください。代わりに、次を実行します。$parser_test <$t
  • [[ $? == 0 ]](新しい構文) または[ $? -eq 0 ](古い構文) のいずれかを使用します。
  • printfの代わりに使用する場合は、行末に手動でecho追加する必要があることを忘れないでください\n
  • 決して使用しないで1> $TMP_FILE 2> $TMP_FILEください - これは、予測できない方法で stdout を stderr で上書きするだけです。標準出力と標準エラーを組み合わせたい場合は、次を使用します。1>$TMP_FILE 2>&1
  • 慣例により、環境変数には ALL_CAPS 名が使用されます。スクリプト内の変数名は、no_caps にすることをお勧めします。
  • $?コマンドを実行した直後に使用する必要はありません。冗長です。代わりに、次を直接実行できます。if command; then ...

すべてを修正すると、スクリプトは次のようになります。

for t in $tests_path1/cmd*.in; do
    if diff "$t.out" <($parser_test <"$t" 2>&1); then
        echo "$t ** TEST PASSED **"
    else
        echo "$t ** TEST FAILED **"
    fi
done

diff の実際の出力を気にしない場合は、>/dev/null直後に追加diffして無音にすることができます。

第三に、私の理解が正しければ、ファイル名は foo.in と foo.out の形式であり、foo.infoo.in.outありません(上記のスクリプトが期待するように)。これが当てはまる場合は、行を次のように変更する必要があります。diff

diff "${t/.in}.out" <($parser_test <"$t" 2>&1)
于 2013-05-13T15:07:18.870 に答える
1

2 番目のテストでは標準エラーをキャプチャしていますが、最初のテスト (およびパイプの例) では stderr がキャプチャされないままであり、おそらくそれが「diff」(意図したしゃれ) です。

おそらく、適切な場所に '2>&1' を追加して、stderr ストリームと stdout ストリームを組み合わせることができます。

。例えば。

diff $t.out <($parser_test cat $t 2>&1)

言うまでもなく、「機能しない」とは何を意味するのかは言いませんが、それは違いが見つからないということですか、それともエラーメッセージで終了するということですか? さらに情報が必要な場合に備えて、明確にしてください。

于 2013-05-13T14:55:06.530 に答える