如何编写Bash脚本遍历指定命名文件并验证程序输出?
看起来你想把单测试用例的脚本扩展成批量测试版本,还要去掉临时文件——这完全可以做到!我帮你写了一个符合需求的脚本,然后一步步解释实现细节:
完整脚本代码
#!/bin/bash # 先检查用户是否传对参数 if [[ $# -ne 2 ]]; then echo "用法: $0 <待测试程序> <测试用例前缀>" echo "举个例子: $0 myfile pattern" exit 1 fi TEST_PROG="$1" PATTERN="$2" # 遍历所有匹配前缀的输入文件 for infile in "${PATTERN}"*.in; do # 如果文件不存在(比如无匹配用例时,infile会是"pattern*.in"字符串),直接跳过 [[ -f "$infile" ]] || continue # 提取测试用例的基础名称(去掉.in后缀) base="${infile%.in}" outfile="${base}.out" errfile="${base}.err" echo "=== 正在测试: $base ===" # 处理标准输出对比 if [[ ! -f "$outfile" ]]; then echo "⚠️ 警告: 找不到对应的输出文件 $outfile,跳过标准输出检查" else # 直接把程序的stdout通过管道传给diff,完全不需要临时文件! if ./${TEST_PROG} < "$infile" | diff -s - "$outfile" >/dev/null; then echo "✅ 标准输出: 与预期一致" else echo "❌ 标准输出: 与预期不符" # 如果想看到具体差异,把下面这行注释去掉: # ./${TEST_PROG} < "$infile" | diff -u - "$outfile" fi fi # 处理标准错误对比 if [[ ! -f "$errfile" ]]; then echo "⚠️ 警告: 找不到对应的错误文件 $errfile,跳过标准错误检查" else # 只捕获程序的stderr,丢弃stdout,然后传给diff对比 if ./${TEST_PROG} < "$infile" 2>&1 >/dev/null | diff -s - "$errfile" >/dev/null; then echo "✅ 标准错误: 与预期一致" else echo "❌ 标准错误: 与预期不符" # 想看差异就去掉注释: # ./${TEST_PROG} < "$infile" 2>&1 >/dev/null | diff -u - "$errfile" fi fi echo "" done
关键实现细节说明
参数校验
开头先检查用户是否传入了两个必要参数(待测试程序和测试用例前缀),避免用户因用法错误导致脚本异常。批量遍历测试用例
用for infile in "${PATTERN}"*.in自动匹配所有符合前缀的输入文件,再通过[[ -f "$infile" ]]过滤掉不存在的文件(比如无任何匹配用例时,避免无效循环),完全符合你提到的「处理存在的用例,跳过不存在的」需求。彻底避免临时文件
- 对比标准输出时,直接把待测试程序的stdout通过管道传给
diff,diff的-表示读取标准输入,全程无临时文件生成。 - 对比标准错误时,用
2>&1 >/dev/null把stderr重定向到stdout,同时丢弃原stdout,再传给diff对比错误文件,同样不需要临时文件。
- 灵活的错误处理
如果某个测试用例对应的.out或.err文件不存在,脚本会给出警告并跳过该部分检查,不会直接报错退出,适配不同的测试用例场景。
使用方式
完全符合你的要求,执行以下命令即可:
./script.sh myfile pattern
它会自动处理所有pattern*.in文件,比如pattern1.in、pattern2.in、pattern4.in,跳过不存在的pattern3.in。
如果需要在不匹配时查看具体差异,只需把脚本中对应的注释行取消注释,diff -u会输出统一格式的差异内容,方便你定位问题。
内容的提问来源于stack exchange,提问作者Blomex
相关产品推荐
相关产品推荐

