0

The command patch -R -p0 -s -f --dry-run < abc.patch fails with exit code 1 and prints a error message from patch command but when used with negation in a if condition it passes (i.e prints Pass), below is the code

if ! patch -R -p0 -s -f --dry-run < abc.patch; then
         echo "Pass"
fi

What I tried ? I redirected string dev/null no change in result

Please help me understand what's going wrong in here ?

Kusalananda
  • 333,661
  • 3
    Isn't that just because it's negated? Or am I misunderstanding the question? – Gordon Davisson Dec 22 '21 at 05:32
  • @GordonDavisson the command exits with non-zero so a negation would have resulted in False which is not happening. – Alex Swift Dec 22 '21 at 06:00
  • 3
    "exits with non-zero" is "false" in shell logic. You seem to know the command fails. Negation makes the result true, a success. – Kamil Maciorowski Dec 22 '21 at 06:06
  • In the context of an exit status, 0 is truthy and nonzero is falsy. This is the opposite of the convention used in most other contexts, but they're both just conventions; there's no universal rule that 0 must be falsy and non-0 must be truthy. – Gordon Davisson Dec 22 '21 at 06:23
  • Maybe use the true and false builtins to understand and compare the outcomes of if true ; then echo A ; fi, if ! true ; then echo A ; fi, if false ; then echo A ; fi, and if ! false ; then echo A ; fi, respectively. – FelixJN Dec 22 '21 at 08:36

2 Answers2

2

Since you negate the exit status of patch for the if statement, the if statement could be read as "if patch fails, output the string Pass".

The if statement tests whether the given command succeeds (true) or fails (false). You can remember this and forget about the rest in this answer if you wish.

When the command fails, its exit status is non-zero, possibly allowing for a closer inspection of the reason for failure. Provided that the utility assigns any meaning to the actual value returned (as e.g. curl and rsync do, see the very end of their manuals), a script may choose to handle an error appropriately.

If the command's exit status is zero, it signals the shell that the utility finished successfully.

The exit status is more of "an error code" rather than "a boolean value" or "true or false". The true/false boolean test is performed internally by the if statement testing the exit status to see whether the utility had a failure condition. If not (exit status is zero), the test is true, i.e., the utility did not fail.

Kusalananda
  • 333,661
0

You obviously wanted to say something like "unless X is wrong, do Y", came to a negated "if" to express "unless", and in the end negated effectively the "wrong", so your "if" succeeds exactly if (and only if) X is wrong (see @they's answer). This has nothing to do with exit codes, just with complexities of negation.

hh skladby
  • 41
  • 2