23

In bash, I sometimes want to run several commands in serial and don't want to wait for them to finish before I type the new ones. So I do something like this:

cmd1; cmd2; cmd3

Unfortunately, one of the commands might fail. In that case, I'd like to stop. Is there an easy way to do this, but make it so that I only keep running the commands if the previous command had a 0 exit code?

39

Use && operator,

cmd1 && cmd2 && cmd3

In shellscripting, && and || operators are modelled after optimized implementation of logical operators in C. && means AND operator, and || means OR. Unix is tightly related to C, and in C, the second operand of logical operators isn't evaluated if the result is already known from the first operand. E.g. "false && x" is false for any x, so there is no need to evaluate x (especially if x is a function call); similarly for "true || x". This is also called short-circuiting semantics.

And in Unix, it is traditional to interpret commands' return values as "successful completion" truth values: exit code 0 means true (success), nonzero means false (failure). So, when the first command in cmd1 && cmd2 returns "false" (nonzero exit status, which indicates failure), the compound command's status is known: failure. So overall interpretation of cmd1 && cmd2 may be: "execute cmd1, AND THEN, if it didn't fail, cmd2". Which is what you basically want in your question.

Similarly with OR: cmd1 || cmd2 can be interpreted as "execute cmd1, OR IF it fails, cmd2".


Protip: for longer chains of &&, consider putting set -e in your script. It basically changes the semicolon ; into &&, with a couple of special cases.

  • 1
    +1 for explaining || – Alp Jun 23 '13 at 13:47
  • can you chain whatever the status of the first command is? (success or failure) – Hugo Trentesaux May 21 '19 at 16:20
  • @HugoTrentesaux what do you mean?.. The success/failure result or A || B is just the same as the [short-circuiting] logical A OR B. A || B is success when A was success, or when A was failure but B was success; and A || B is failure when A was failure and B was failure. Similarly for &&, it follows logical AND. – ulidtko May 21 '19 at 16:35
  • In the shell context, how can I execute A and then B no matter if A fails or succeeds? – Hugo Trentesaux May 24 '19 at 17:44
  • 1
    @HugoTrentesaux that's what the plain regular ; (or newline) does by default. set -e will turn ; into &&, roughly speaking. set +e [the default] turns A; B into what you say: run A, then no-matter-what run B. – ulidtko May 27 '19 at 11:04
13

"Chaining Commands an grouping them"

ping 192.168.0.1 || { echo "ping not successful"; exit 1; }

pings, only if not successful, executes the chained group of commands in brackets.

Attention:

The list has to be terminated with a ";".

There must be blank spaces between brackets and the grouped commands!

6

Simply with the && operator. For instance:

cmd1 && cmd2 && cmd3

If one of the commands fails (returns an exit value other than 0), the other commands won't run.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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