Unix’s mysterious && and ||

Unix’s mysterious && and ||
Credit: Chrismatos

The Unix shell’s && and || operators provide some very useful functionality, but they can be a bit mysterious, especially considering the number of options for how they are used.

The most common use of these Boolean operators is in the construction of multi-conditional tests—when you want two or more conditions to be true (or any in a set of operators to be true) before some command is run. The && serves as a logical AND (requiring all conditions to be true) operation, while the || provides a logical OR (requiring only one to be true).

Combining tests

In the script below, we’re using && to combine two very simple conditions. We won’t get output unless both conditions are true. This particular script runs through the tests twice, but only to demonstrate the two “flavors” of the brackets that can be used. Note that && doesn’t work inside square brackets unless they’re doubled.

#!/bin/bash

echo $1 $2

if [ $1 == "a" ] && [ $2 == "b" ]
then
  echo c
fi

if [[ $1 == "a" && $2 == "b" ]]
then
  echo c
fi

This script will output a "c" twice if the first argument ia "a" or if the second is "b". It will do the same thing if the first two arguments are "a" and "b".

if [ $1 == "a" ] || [ $2 == "b" ]
then
  echo c
fi

if [[ $1 == "a" || $2 == "b" ]]
then
  echo c
fi

The double brackets allow you to put the && and || between the tests themselves. This is a newer syntax and may not be supported by every shell.

The Boolean logic of commands

Interestingly, that we put on each side of a && or || operator, however, doesn’t need to be a test. They can be commands. If we put a command on each side, the command on the right of a && will be run only if the command on the left is successful. The command on the right of a || will be run only if the command on the left fails.

The reason for this behavior is tied to the Boolean nature of the operators. If a command runs successfully, the result is evaluated as "true". If a command fails, the result is evaluated as "false".

So, we get this behavior:

$ echo hello || echo byebye
hello

$ echo hello && echo goodbye
hello
goodbye

In the first command above, we see only “hello” in the output because with an OR, satisfaction on the left side is all that is required for the overall command line to be satisfied. In the second command, both echo commands are run because both sides need to be run for an AND connection.

Using && or || to exit loops

You can also use && to exit a loop once some condition is met. The script below will loop until a file named /tmp/wait4me is available (exists and is readable) and will then exit via the break command. Note that we're also suppressing error messages by sending that output to /dev/null.

#!/bin/bash

while true
do
  tail /tmp/wait4me 2> /dev/null && break
  sleep 2
done

If you had coded the loop this way instead, it would exit as soon as the /tmp/wait4me file was no longer accessible.

#!/bin/bash

while true
do
  tail /tmp/wait4me 2>/dev/null || break
  sleep 2
done

Wrapping up

The && and || operators can be useful in a number of ways and, hopefully, are a little less mysterious than they might have seemed.

Join the Network World communities on Facebook and LinkedIn to comment on topics that are top of mind.
Related:
Must read: 10 new UI features coming to Windows 10