What is the point of the bash Null-operator ":", colon?

9,699

Solution 1

It's sometimes useful to allow parameter expansions side-effects to occur.

For example, setting a default value

read -p "Enter your name: " name
: ${name:=John Doe}  # if the user entered an empty string
echo "$name"

Solution 2

You can also use it for endless loops:

while : ; do 
   # ....
done

Solution 3

You can use it to create a file without running a program::

: > /path/to/file

This is infinitesimally faster than touch /path/to/file (since it doesn't require running the touch program) and may be marginally more portable than just plain

> /path/to/file

which seems to work on many systems.  Similarly, it can be used to check whether you have write access to a file:

if { : >> /path/to/file;} 2> /dev/null
then
    echo "writeable"
else
    echo "write permission denied"
fi

although this, also, can generally be done without the :.  Caveats:

  • This doesn’t check whether the file already exists.  If it doesn’t, this will create the file if it has permission to do so.
  • If the file doesn’t exist, and your script doesn’t have permission to create it, this will report “write permission denied”.

(See the linked question for reasons why this is more reliable than if [ -w /path/to/file ].)

Solution 4

Way back, in Unix V6 and Thompson Shell, the : was actually used as part of the goto statement. According to the manual, it originally appeared in version 3 of Unix:

The entire command file is searched for a line beginning with a : as the first non-blank character, followed by one or more blanks, and then the label. If such a line is found, goto repositions the command-file offset to the line after the label and exits. This causes the shell to transfer to the labelled line.

Nowadays, in bash, it's used as a no-op operator, returning success. Indeed, if you look at the source code, you'll see that both true and : use same function, int colon_builtin(), underneath. There's no : non-builtin command, and /bin/true is actually a fairly large command for what it does.

: could be used anywhere true is used, for example in command_that_can_fail || true, though that's likely to confuse non-experts. Read more about it here.

Solution 5

You can use it on the positive test of an if command when you only want to do something on the negative side. For example:

if [[ True == False ]]; then
    :
else
    echo "true <> flase"
fi

Without the : bash would generate a syntax error.

This is an oversimplified example. Generally you would use such a technique in preliminary coding when you haven't written that code segment yet and just need something that doesn't generate an error.

Share:
9,699

Related videos on Youtube

Justin
Author by

Justin

Updated on September 18, 2022

Comments

  • Justin
    Justin over 1 year

    What is the point of the "null" operator in a BASH script? I understand that it is used as a placeholder following an if command when you have nothing to say, but need a command to allow the program to run properly. But what is the overall use for it? When would you use it? When does it make sense to use it?

  • Iluvathar
    Iluvathar over 9 years
    Could you explain symbol-by-symbol how the second line works?
  • fiatux
    fiatux over 9 years
    Read about the : command and parameter expansion in the bash manual.
  • kjh
    kjh almost 8 years
    To outline what @glennjackman is referencing, the second line calls the null command :, and ${name:="John Doe"} will be expanded, causing the assignment to take place because it is read as an argument to :. Without the : the shell will attempt to run "John Doe" as a command, or the value $name if it is already set
  • Sergiy Kolodyazhnyy
    Sergiy Kolodyazhnyy almost 6 years
    Good answer, although it may not be apparent at first, that this is most useful with an actual command within the test condition, for instance if pgrep firefox >/dev/null ; then : ; else echo "Firefox not running"; fi would show error only if firefox wasn't running. In other words, when you need to do something only when command has an error. In a way this is equivalent to pgrep firefox || echo "Firefox not running", although more readable and allows more commands