【问题标题】:Checking diff exit status in a script检查脚本中的差异退出状态
【发布时间】:2014-05-06 14:25:51
【问题描述】:

在命令行上,对两个不同的文件使用 diff 后,命令

echo $?   

报告“1”。当我在脚本中尝试相同时,如下所示:

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

然后我从不打印“失败”(即使是不同的文件)。请注意,这是 bash shell,所以语法应该没问题(例如,如果我改为检查 '0',它总是会打印出来)。

如何检查 diff 命令是否发现了差异,并在此条件下进行处理?

这是在 Ubuntu 12.04 下。

【问题讨论】:

  • 如果您只对返回码感兴趣,请使用 cmp 而不是 diff
  • echo $(diff)echo 返回退出代码,而不是从diff
  • @RedX:您的第二条评论回答了为什么它不起作用,谢谢。但我想先打印差异,还要跟踪有多少比较失败。你觉得有一个简单的方法吗?
  • diff 不输出不匹配的计数 AFAIK。 var=$(diff "$F1" "$F2"); ret=$?; echo "$var"; if (($ret == 0)); then echo "same"; else echo "not same"; fi
  • 未测试:TMPFILE=.tmp.$$; if diff "${F1}" "${F2}" > "${TMPFILE}; then echo "There were $(wc -l "${TMPFILE}") differences;"; cat "${TMPFILE}"; else echo "Same same!"; fi ; rm -f "${TMPFILE}"

标签: linux bash unix exit-code


【解决方案1】:

来自您的评论:

但我想先打印差异,但还要跟踪有多少比较失败。

我不知道 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:如果您将wc -l 替换为grep -c '^[0-9]',您将获得实际的差异计数
【解决方案2】:

您看不到来自diff 的返回值,因为最后运行的命令实际上是echo,而您看到的是它的返回值。您应该能够使用以下代码达到预期的效果(捕获然后回显diff 的输出是不必要的 - 只需让它写入标准输出):

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

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

【讨论】:

  • 谢谢,但我还需要打印差异;所以@RedCricket 的答案正是我所需要的。
  • echo "`cmd`" 构造毫无意义。您正在捕获cmd 写给stdout 的内容,然后...立即将其写给stdout。正如所写,它什么也没做(除了 - 正如您发现的那样 - 无法获得 cmd 的返回值)。
  • @RedCricket 同意,尽管 RedX 的回答对于(部分)解决计算差异的要求也有好处。您可以通过使用指向此(以及 RedX 的)答案的序言来更新您的答案来帮助解决这个问题。
【解决方案3】:

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

【讨论】:

    【解决方案4】:

    您可能想要这样做。

    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 是的,我运行了 diff 两次……那又怎样?
    • 使用具有固定名称的临时文件的缺点是无法在任何类型的并行工作中使用此脚本。
    • 比赛条件。不能保证diff 的两次调用会产生相同的结果。
    • Andrew Medico 下面的答案是更好的答案。
    猜你喜欢
    • 2013-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-01
    • 2020-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多