Checking diff exit status in a script
Solution 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
Solution 2
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.
Solution 3
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
Solution 4
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
.
Related videos on Youtube

gnometorule
I like fish! And agonizing over solving the Finite Sub-Cuddling hypothesis! The chameleon, incidentally, says "Maaaaaaaaaaaaaaaaattthh!"
Updated on June 26, 2022Comments
-
gnometorule 6 months
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.
-
RedX over 8 yearsUse
cmp
instead ofdiff
if you are only interested in return codes. -
RedX over 8 yearsAnd
echo $(diff)
returns the exit code fromecho
, not fromdiff
. -
Steve Carter over 6 yearsNot 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}"
-
-
ceving over 8 years@ꜱᴀᴍᴏᴛʜ then the echo would not print the result
-
Red Cricket over 8 years@ceving yeah I run diff twice ... so what?
-
ceving over 8 years@RedCricket Your question is a -1 worth.
-
Red Cricket over 8 years@ceving So what's you solution then?
-
ceving over 8 years@RedCricket
echo $rv
-
gnometorule over 8 yearsThat does the trick! And a good standard trick (?) learned.Thanks! (it's clever and useful, so don't understand the confusion about the answer :))
-
gnometorule over 8 yearsThanks, but I need to also print the diff; so @RedCricket 's answer was exactly what I needed.
-
gnometorule over 8 yearsVery nice! That does even more than I want. Diff is binary (as you probably know): 1 - differences, 0 - none.
-
RedX over 8 yearsUsing temp files with fixed names has the disadvantage of not enabling you to use this script in any kind of parallel work.
-
nobody over 8 yearsRace conditions. There's no guarantee that the two invocations of
diff
will have the same result. -
nobody over 8 yearsThe
echo "`cmd`"
construct is pointless. You're capturing whatcmd
wrote tostdout
and... immediately writing it tostdout
. As written, it accomplishes nothing (except - as you've discovered - making impossible to get the return value ofcmd
). -
mklement0 over 8 years@gnometorule: If you replace
wc -l
withgrep -c '^[0-9]'
, you will get the actual difference count. -
Red Cricket over 8 yearsWell it just goes to show you, it's always something, you either got a toenail in your hamburger or toilet paper clinging to your shoe. Roseanne Roseannadanna
-
mklement0 over 8 years@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.
-
Red Cricket over 8 yearsAndrew Medico's answer below is the better answer.