17

If I run diff -q on two files and they are identical, the exit code generated by echo $? is 0; if the files differ, the exit code is 1. Why is that? In what way is the first diff a success and the second a failure?

I used the terms "success" and "failure" based on my reading and limited understanding of http://mywiki.wooledge.org/BashGuide/TestsAndConditionals:

  1. Exit Status
    Every command results in an exit code whenever it terminates.
    This exit code is used by whatever application started it to evaluate
    whether everything went OK. This exit code is like a return value from
    functions. It's an integer between 0 and 255 (inclusive). Convention
    dictates that we use 0 to denote success, and any other number to denote
    failure of some sort. The specific number is entirely application-specific,
    and is used to hint as to what exactly went wrong.

I should have read man diff right to the end where the convention used by the developers is clear.

muru
  • 207,970
DK Bose
  • 44,703
  • 3
    The real question is: when running diff, is finding a difference a success or a failure? – kos Nov 16 '15 at 17:55
  • Neither a success nor a failure, but a bit of information to be used in further processing. diff can be used to answer "Is this file the same as that file?" Where is the "success" in that? – waltinator Nov 16 '15 at 21:23
  • FWIW, think why 0 is success and non-zero, including 1, is failure - there is (usually) only one successful outcome, but many failure conditions. Similarly, two files can be non-differing in only one way - the contents are identical, but differ in any number of ways. – muru Oct 19 '23 at 13:49

2 Answers2

27

From man diff:

Exit status is 0 if inputs are the same, 1 if different, 2 if trouble.

I freely admit this might not be completely standard but exit codes are more what you'd call "guidelines" than actual rules.

enter image description here

In this case, deviating from the standard allows you to easily run diff in scripts.

diff a b && echo "no difference" || echo "differences!"

This is similar to grep which will exit 0 is something is found, and 1 if something isn't found. I can't explain the orientation between 0 and 1 for diff. I assume they went with C-standard boolean outcomes.

It doesn't really matter. It's just an arbitrary number.

Oli
  • 299,936
  • Sadly this is more like || echo "differences! OR something failed fatally; you'll never know which.", for example if one of the input files is missing, it'll think of it as a "difference", even though it's an actual error. Similar for unreadable inputs, etc. – TWiStErRob Oct 19 '23 at 12:42
  • This is not correct, because you simply assumed that diff would never fail. You need to check whether the exit code is 1 or > 1. – xuhdev Apr 07 '24 at 07:24
7

man diff tells us

EXIT STATUS

   The following exit values shall be returned:

    0     No differences were found.

    1     Differences were found.

   >1     An error occurred.

Your calling the exit values "success" and "failure" is a self-limiting choice.Programs have a whole 8 bits for exit status, values from 0 to 255.

  • 1
    Technically, exit stati can be negative (which often means killed by a signal with number - exit status.) – heiner Jul 15 '22 at 21:18