13

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?

16

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"
  • 2
    Could you explain symbol-by-symbol how the second line works? – Ruslan Nov 15 '14 at 8:43
  • Read about the : command and parameter expansion in the bash manual. – glenn jackman Nov 17 '14 at 0:51
  • 4
    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 – imkendal Jul 7 '16 at 15:39
13

You can also use it for endless loops:

while : ; do 
   # ....
done
  • 4
    But perhaps while true is more readable, because (a) it uses less punctuation, and (b) it is more similar to C-derived languages. – wchargin Nov 15 '14 at 1:47
9

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 ].)

5

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.

3

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.

  • 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 – Sergiy Kolodyazhnyy Jul 13 '18 at 2:24
0

I just used it in a script with SSH commands to keep the script from erroring out.

In this case, I want to see if a user can connect to a set of servers. If the connection is OK, the remote host will echo OK. If the connection fails, SSH will respond with the error. However, I want my script to exit with 0 and not the value of the SSH command if it fails. So essentially I trap the SSH error by ORing it || with the null command :. Looks like this:

#!/bin/bash
for i in $(cat servers.txt); do
    echo -n "$i "; 
    ssh user@${i} 'echo OK' || :; 
done

That way I get the output from SSH but not the error code:

....
swl06 ok
swl07 ok
swl08 Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
swl09 ok
swl10 Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
....

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.