3

On the command line, after using diff on two files that differ, the command

echo $?   

reports back '1'. When I try the same in a script, as follows:

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

then I never print 'failed' (even for differing files). Note that this is the bash shell, so the grammar should be fine (eg, if I check for '0' instead, it always prints).

How can I check if the diff command discovered differences, and process conditionally on that?

This is under Ubuntu 12.04.

5
  • 1
    Use cmp instead of diff if you are only interested in return codes. Commented May 6, 2014 at 14:26
  • 2
    And echo $(diff) returns the exit code from echo, not from diff. Commented May 6, 2014 at 14:27
  • @RedX: your second comment answers why it doesn't work, thanks. But I would like to print the differences first, but also keep track of how many comparisons failed. Do you see an easy way to do that? Commented May 6, 2014 at 14:31
  • diff does not output the count of mismatches AFAIK. var=$(diff "$F1" "$F2"); ret=$?; echo "$var"; if (($ret == 0)); then echo "same"; else echo "not same"; fi Commented May 6, 2014 at 14:34
  • 1
    Not tested: 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}" Commented May 19, 2016 at 9:51

4 Answers 4

6

You're not seeing the return value from diff because the last command run is actually echo and you're seeing its return value. You should be able to achieve the desired effect with the following code (capturing and then echoing the output of diff is unnecessary - just let it write to stdout):

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

Also, note that diff returns a value greater than one on error (0 indicates identical files, 1 indicates different files). You may want to check for and handle that case.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, but I need to also print the diff; so @RedCricket 's answer was exactly what I needed.
The echo "`cmd`" construct is pointless. You're capturing what cmd wrote to stdout and... immediately writing it to stdout. As written, it accomplishes nothing (except - as you've discovered - making impossible to get the return value of cmd).
@RedCricket Agreed, though RedX's answer also has merit for (partially) addressing the count-the-differences requirement. You could help address that by updating your answer with a preamble that points to this (and also RedX's) answer.
5

From your comment:

But I would like to print the differences first, but also keep track of how many comparisons failed.

I don't know if diff outputs the number of differences in the exit code. I think not. But you could count the lines maybe...

Here is how you can store the exit code and count the number of different lines

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

2 Comments

Very nice! That does even more than I want. Diff is binary (as you probably know): 1 - differences, 0 - none.
@gnometorule: If you replace wc -l with grep -c '^[0-9]', you will get the actual difference count.
3

It seems to be because, in your script, $? is the return status of your echo line (not the previous program), and echo will probably always work and return 0.

Comments

1

You probably want to do this instead.

echo "`diff $F1 $F2`"
diff $F1 $F2 > /dev/null 2>&1
rv=$?
...

because $? is get set to 0 by the successful execution of echo.

And if you don't want to run diff twice you could do this too ..

   diff $F1 $F2 > /tmp/thediff 2>&1
   if [ $? != 0 ]
   then
      cat /tmp/thediff
   fi

10 Comments

@ꜱᴀᴍᴏᴛʜ then the echo would not print the result
@ceving yeah I run diff twice ... so what?
Using temp files with fixed names has the disadvantage of not enabling you to use this script in any kind of parallel work.
Race conditions. There's no guarantee that the two invocations of diff will have the same result.
Andrew Medico's answer below is the better answer.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.