在脚本中检查diff命令的退出状态

3
在命令行中,当使用diff比较两个不同的文件后,该命令将会显示:
echo $?   

回报“1”。当我尝试在脚本中执行相同操作时,代码如下:

echo "` diff $F1 $F2`"   
rv=$?  
if [[ $rv == 1 ]]  
then    
    echo "failed"    
fi        

那么我从来没有打印“failed”(即使是针对不同的文件)。请注意,这是Bash shell,因此语法应该没问题(例如,如果我检查“0”,它总是打印)。

我如何检查diff命令是否发现了差异,并有条件地进行处理?

这是在Ubuntu 12.04下执行的。


1
如果您只关心返回代码,请使用 cmp 而不是 diff - RedX
2
echo $(diff) 返回的退出码是来自于 echo,而不是 diff - RedX
@RedX:你的第二条评论回答了为什么它不起作用,谢谢。但我想先打印出差异,同时也要跟踪失败的比较次数。你看有没有简单的方法可以做到这一点? - gnometorule
据我所知,diff命令不会输出不匹配的数量。以下是代码:var=$(diff "$F1" "$F2"); ret=$?; echo "$var"; if (($ret == 0)); then echo "same"; else echo "not same"; fi - RedX
1
未测试: TMPFILE=.tmp.$$; 如果 diff "${F1}" "${F2}" > "${TMPFILE}"; 然后 echo "有 $(wc -l "${TMPFILE}") 处不同;"; cat "${TMPFILE}"; 否则 echo "一样一样的!"; fi ; rm -f "${TMPFILE}" - Steve Carter
4个回答

6

您没有看到diff的返回值,因为最后运行的命令实际上是echo,您看到的是它的返回值。您应该能够通过以下代码实现所需的效果(捕获然后回显diff的输出是不必要的 -只需让它写入stdout):

diff $F1 $F2
rv=$?  
if [[ $rv == 1 ]]  
then    
    echo "failed"    
fi

此外,请注意 diff 在出错时返回大于一的值(0 表示文件相同,1 表示文件不同)。您可能需要检查并处理这种情况。

1
谢谢,但我还需要打印差异;所以@RedCricket的答案正是我所需要的。 - gnometorule
2
“echo "`cmd`"” 结构是无意义的。你正在捕获 cmd 写入 stdout 的内容,然后立即将其写入 stdout。按照现有的写法,它什么也没有实现(除了 - 正如你发现的那样 - 使得获取 cmd 的返回值变得不可能)。 - nobody
@RedCricket 同意,不过 RedX 的回答也有一定的价值,因为它(部分地)解决了计算差异要求。你可以通过更新你的回答并在开头指向这个(以及 RedX 的)回答来帮助解决这个问题。 - mklement0

5

根据您的评论:

但我希望先打印出差异,并记录有多少次比较失败。

我不知道diff是否在退出代码中输出差异数。我认为不会。但是您可以尝试计算行数...

以下是如何存储退出代码并计算不同行数的方法:

var=$(diff "$F1" "$F2")
#store diff exit code
exit_code=$?
# remember that this is not the same as count of differences
lines_output_by_diff=$(wc -l <<< "$var")

echo "$var"

if (($exit_code == 0)); then
  echo "same"
else
  echo "not same"
fi

非常好!它甚至比我想要的还要多。Diff是二进制的(正如您可能知道的):1-差异,0-无差异。 - gnometorule
2
е¶ВжЮЬдљ†зФ®grep -c '^[0-9]'жЫњжНҐwc -lпЉМдљ†е∞ЖеЊЧеИ∞еЃЮйЩЕзЪДеЈЃеЉВиЃ°жХ∞гАВ - mklement0

3
似乎是因为在您的脚本中,$? 是您的 echo 行的返回状态(而不是之前的程序),而 echo 可能总是有效并返回 0

1
你可能想要做这个。
echo "`diff $F1 $F2`"
diff $F1 $F2 > /dev/null 2>&1
rv=$?
...

因为成功执行echo后,$?被设置为0。
如果您不想运行两次diff,也可以这样做...
   diff $F1 $F2 > /tmp/thediff 2>&1
   if [ $? != 0 ]
   then
      cat /tmp/thediff
   fi

如果@ꜱᴀᴍᴏᴛʜ不存在,那么echo将不会打印结果。 - ceving
@ceving 是的,我运行了两次 diff ... 那又怎样? - Red Cricket
3
使用固定名称的临时文件的缺点是无法在任何类型的并行工作中使用该脚本。 - RedX
1
竞态条件。不能保证两次调用“diff”会产生相同的结果。 - nobody
1
Andrew Medico的下面的回答是更好的答案。 - Red Cricket
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接