我正在尝试编写循环,但这不起作用:
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显示输出不同(很奇怪,我看到输出所需的错误行,因为它打印到stdout,而不是被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
我必须避免使用临时文件。为什么第一个循环不起作用以及如何解决它? 谢谢。
P.S。文件* .in包含程序的错误命令行参数,* .out包含程序必须为这些参数打印的错误消息。
答案 0 :(得分:4)
首先,对于您的错误,您需要重定向标准错误:
diff $t.out <($parser_test `cat $t` 2>&1)
其次,对于您可能不了解的所有其他问题:
ls
与for
循环一起使用(它有很多问题,例如包含空格的文件名中的意外行为);相反,请使用:for t in $TESTS_PATH1/cmd*.in; do
"$t"
而不是$t
$(command)
$parser_test <$t
[[ $? == 0 ]]
(新语法)或[ $? -eq 0 ]
(旧语法)printf
代替echo
,请不要忘记您需要手动在行尾添加\n
1> $TMP_FILE 2> $TMP_FILE
- 这只是以不可预测的方式用stderr覆盖stdout。如果要合并标准输出和标准错误,请使用:1>$TMP_FILE 2>&1
$?
,这是多余的。相反,您可以直接运行: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
如果您不关心差异的实际输出,可以在>/dev/null
之后立即添加diff
以使其静音。
第三,如果我理解正确,你的文件名是 foo.in 和 foo.out ,而不是 foo.in 和 foo.in.out (就像上面的脚本所期望的那样)。如果是这样,您需要将diff
行更改为:
diff "${t/.in}.out" <($parser_test <"$t" 2>&1)
答案 1 :(得分:1)
在你的第二个测试中,你正在捕获标准错误,但是在第一个测试中(和管道示例)stderr仍然没有被捕获,也许这就是“差异”(双关语)。
您可以在适当的位置添加'2&gt;&amp; 1'来合并stderr和stdout流。
.eg。
diff $t.out <($parser_test
cat $t
2>&1)
更不用说,你没有说“什么不行”意味着,这是否意味着它没有找到差异,或者它是否以错误信息退出?如果您需要更多信息,请澄清。