Bash脚本用diff对比文件与程序输出异常及存储输出问询
我写了个脚本,想用diff命令把预期输出文件和指定程序($1)运行输入文件后的输出做对比,但脚本一直无响应(持续运行)。如果把<($1 $file)换成普通文件的话,脚本就能正常执行,实在搞不懂哪里出问题了。我的脚本代码如下:
for file in $2/*.in do if diff ${file%in}out <($1 $file) >/dev/null; then echo "something."; else echo "something2." fi done
另外,有没有办法把$1 $file的输出存储到变量里?当对比相同文件(${file%in}out)时,会得到类似so...的内容。
问题分析与解决办法
首先来说脚本卡住的问题,大概率是这几个原因:
循环语法错误:你的
for循环写法有问题,do前面需要加分号或者换行,正确的写法应该是:for file in "$2"/*.in; do给
$2加引号是为了避免路径包含空格时出现解析错误,这也是脚本编写里的常见坑。程序本身卡住:脚本无响应最可能的原因是你指定的程序
$1在运行$file时没有正常退出——比如程序需要交互式输入、没正确读取输入文件内容,或者陷入了死循环。你可以先单独在终端运行$1 $file,看看能不能正常输出结果并回到命令提示符,如果运行后终端一直停着,那就是程序本身的问题,得先解决程序的退出逻辑。shell兼容性问题:
<()这种进程替换语法是bash/zsh的特性,如果你的脚本用的是dash这类轻量shell(比如某些系统默认sh指向dash),这个语法会失效,导致脚本异常。解决办法是在脚本开头加上#!/bin/bash,明确指定用bash来运行脚本。
然后说把程序输出存到变量的问题,用命令替换就能轻松实现:
# 把程序输出存入output变量 output="$("$1" "$file")"
如果需要保留输出里的换行符,这个写法也能正常生效。之后要对比的话,可以用:
if diff "${file%in}out" <(echo "$output") >/dev/null; then # 原有逻辑不变 fi
或者也可以把变量内容写入临时文件再和预期文件对比,不过用进程替换更简洁。
最后给你个调试小技巧:先把diff后面的>/dev/null去掉,这样能看到diff的具体输出,或者直接查看$1 $file的输出内容,方便快速排查问题。
内容的提问来源于stack exchange,提问作者mikol

