0

I am curious about the logic behind && in continuous commands execution in shell.

Lets see an example: command_a && command_b && command_c

In shell, this means that once a command fails, the consequent commands will not execute and the chain should stop.

If we replace each command by its exit code, the chain becomes, for example this expression 0 && 1 && 0. (command_a succeed, command_b failed, command_c succeed)

If we try evaluating this expression, the evaluation should stop right after the first command, 0 value.

If && logic is replaced by ||, the expression would be more fit to the meaning of original chained command. 0 || 1 || 0.

Expression's evaluation stops after command_b execution

1
  • 3
    Hint: exit code 0 is TRUE and 1 is FALSE
    – slebetman
    Commented Mar 2, 2017 at 15:33

4 Answers 4

4

There's a difference between the semantics of a successful command and the representation of success via the numeric value of the exit code. If you consider the abstract "is a command successful", && makes more sense, since the "success" abstract boolean is true. That's why && is used. You need A to run, AND you need B to run.

But, due to the fact that there's usually only one status for success, but many different types of errors, the value 0 has been defined long ago to be used for exit status to indicate success.

So, the exit status of a command can simply not replace the command itself in such an expression. The semantics and the representation are just different.

1

Check out this post.

"The right side of && will only be evaluated if the exit status of the left side is zero. || is the opposite: it will evaluate the right side only if the left side exit status is nonzero..."

$ false && echo howdy!

$ true && echo howdy!
howdy!
$ true || echo howdy!

$ false || echo howdy!
howdy!
2
  • FYI, "code snippets" are for HTML -- content that can run in a browser -- which is why your question right now has a "Run code snippet" button that doesn't actually do anything. Use the {} button or four-space indents for other code-formatting. Commented Mar 2, 2017 at 14:59
  • Thanks @CharlesDuffy for that tip! Commented Mar 2, 2017 at 14:59
1

I have seen || used in some shell script too. I think it depends on the occasions. You may use command-a && command-b when you want command-b to be executed only after command-a success.

Likewise, you may use command-a || command-b to deal with the situation when command-a fails.

0

Update: After reading your question three times I now understand what puzzles you: That 0 represents success, and/or (sic) that logical operators treat it as true. Yes, that can be confusing, coming from C. The other Peter's answer explains that well. I let my original answer stand anyway because it is not "wrong".


It is what logic dictates if commands are impossible to perform or don't make sense unless their predecessors succeeded. That happens quite often: "Retrieve a HTML document from the web, verify the time stamp, parse a value out of it, and write that value as an updated data somewhere." Each step depends on the success of all preceding steps.

If, instead, you have something "retrieve a document from the web, or from the cache, or from disk, or take a default here document, in this order of preference", then the appropriate way to write that is indeed with logical ORs. This happens but is less common.

ORing is a common idiom though for error handling, because subsequent commands are exactly performed if the pervious failed. Consider Perl's idiomatic cmd() || die();. (You have more lives. Phew.)

1
  • 1
    ...though for purposes of exit status, it's true in C too -- see the constants EXIT_SUCCESS and EXIT_FAILURE defined in stdlib.h. Commented Mar 2, 2017 at 17:37

Not the answer you're looking for? Browse other questions tagged or ask your own question.