我正在尝试编写一个循环,但这不起作用:
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
Run Code Online (Sandbox Code Playgroud)
这也没有帮助:
$parser_test `cat $t` | $DIFF $t.out -
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
我必须避免使用临时文件。为什么第一个循环不起作用以及如何修复它?谢谢。
PS 文件 *.in 包含程序的错误命令行参数,而 *.out 包含程序必须为这些参数打印的错误消息。
首先,对于您的错误,您需要重定向标准错误:
diff $t.out <($parser_test `cat $t` 2>&1)
Run Code Online (Sandbox Code Playgroud)
其次,对于您可能不知道的所有其他问题:
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
Run Code Online (Sandbox Code Playgroud)
如果您不关心 diff 的实际输出,您可以>/dev/null
在后面添加diff
以使其静音。
第三,如果我理解正确,您的文件名的形式为foo.in和foo.out,而不是foo.in和foo.in.out(如上面的脚本所期望的)。如果这是真的,您需要将该diff
行更改为:
diff "${t/.in}.out" <($parser_test <"$t" 2>&1)
Run Code Online (Sandbox Code Playgroud)