6

In bash what does the syntax ||: do?


Example

$ ls foo ||:

Other than always return success, does this do anything else special?

Is the output of $ ls foo ||:; echo $? always zero, even if ls foo fails because foo doesn't exist?

I saw it in a script that begins with set -e. So I'm guessing it ensures that no error occurs, thus the script does not immediately exit, even if a command suffixed by this returns an error.

Elliptical view
  • 3,921
  • 4
  • 27
  • 46

2 Answers2

8

It only returns success if the command before it did not return success.

With set -e (aka set -o errexit), a command line returning an error would abort the script. If you add this ||: to the end of a command line, there will be no error (because, if there were, the next command would return true).

It basically says: if there was an error in the previous command, run true so that the command line ends without an error and the script can go on.

This script will abort without displaying the date because ls returns an error:

set -e
ls -l /tmp/nonexistentfile
date

But this script will not abort and it will display the date, since the last command is : (true):

set -e
ls -l /tmp/nonexistentfile || :
date
4

There are two separate pieces of syntax here:

||  This is the OR symbol. 
:   This is a dummy command which will return a success (return code 0)

In combination with a command this has the effect of first running the command and having the line return 'success' irrespective of the return code of the first command. Since either the command will return True, OR : (do nothing successfully) will be returned.

Separately set -e has the effect of exiting a script if any statement in that script returns False. Therefore ||: is acting as a 'guard', ensuring the script continues even if the command on that line returns False

David258
  • 178
  • 2
    : is not a symbol for true, it is a dummy command i.e. it does not do anything and ignores any parameters. In contrast to a comment sign the rest of the line is executed regularly. That is useful for debugging or if you want something executed that is part of any command like ${parameter:=word}. The shell builtin : behaves like the shell builtin true. But I would not call it a "symbol for true". A : command can still lead to a non-zero exit code: : <nofile – Hauke Laging Jun 05 '20 at 13:44
  • @HaukeLaging - thanks for the comment; learned something new today. I will edit my post accordingly – David258 Jun 05 '20 at 13:55
  • 6
    @HaukeLaging true <nofile will result in exactly the same error, since the error is produced by bash's file opening stage, not true or : command. – Ruslan Jun 05 '20 at 14:01