Saturday, 3 September 2016

Command Chaining with && and ||

Command Chaining with && and ||

We can chain command using the logical AND (&&) operator or the logical OR (||) operator.
They work like this.

&&-operator

The command on the right side of && will only be executed if the command on the left side of && sets and exit code of 0.

||-operator

The command on the right side of || will only be executed if the command on the left side of ||sets an exit code other than 0, i.e. signals an error condition.

Examples

The examples to follow use another method of chaining command, which is the “;” operator. This one simply chains commands disregarding their respective exit code. I use “;” to isolate the workings of && and ||.


Here are some straight forward examples.

Example 1

$ # example 1
$ # simple use of &&
$ mkdir /test && echo "$?: directory created"; echo "$?: this is the second command"
mkdir: cannot create directory ‘/test’: Permission denied
1: this is the second command

Due to the error, the command to the right of && was not executed. The exit code was still 1 when the next echo was executed.

Example 2:

Now the same check with an initial command that works:

$ mkdir /vagrant/test && echo "$?: directory created"; echo "$?: this is the second command"
0: directory created
0: this is the second command


This time the initial command sets exit code 0 which cases the first echo to be executed. The second echo is then executed unconditionally.

Example 3

The combination of && and || is often used to simulate an if-else on one line.
$ # example 3
$ # if-else simulation
$ #
$ # initial command failes
$ mkdir /test && echo "$?: directory created" || echo "$?: directory creation failed"
mkdir: cannot create directory ‘/test’: Permission denied
1: directory creation failed
$ #
$ # initila command succeeds
$ mkdir /vagrant/test && echo "$?: directory created" || echo "$?: directory creation failed"
0: directory created

It really looks like it works if-else like.
But don’t be fooled, it’s only a simulation that breaks down easily, as the next example shows:

Example 4:

In this example, we let the second command, the one that represents the if-case, fail.

$ # example 4
$ # not really if-else
$ mkdir /vagrant/test && mkdir /test || echo "$?: /vagrant/test could not be created"
mkdir: cannot create directory ‘/test’: Permission denied
1: /vagrant/test could not be created


This is what happened:
  • The initial command succeeded, causing the second command to be executed
  • The second command fails, causing the third command (representing the else-case) to be executed

This was probably not what was intended.
But it demonstrates that && and || are simply chaining the commands in a row and execute them based on the exit code of the previous command.
The last example supports this.

Example 5

Here we turned the sequence of && and || around and again let the initial command fail.

$ # example 5
$ mkdir /test || echo "$?: directory creation failed" && echo "$?: directory created"
mkdir: cannot create directory ‘/test’: Permission denied
1: directory creation failed
0: directory created


This is what happened:
  • The initial command failed, causing an exit status of 1, causing the first echo to be executed
  • The first echo completed successfully, causing an exit status of 0, causing the second echo to be executed

Takeaway: && and || are simply chaining commands on condition.

No comments:

Post a Comment