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?

- 13,065
- 5
- 49
- 65

- 2,121
-
also read Using a Colon As A Bash Null Operator – αғsнιη Nov 14 '14 at 16:32
-
2The reason you cite is a pretty important one. Why do you need more? – terdon Nov 14 '14 at 17:39
7 Answers
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"

- 17,900
-
2
-
Read about the
:
command and parameter expansion in the bash manual. – glenn jackman Nov 17 '14 at 00:51 -
6To 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
– kjh Jul 07 '16 at 15:39$name
if it is already set
You can also use it for endless loops:
while : ; do
# ....
done

- 9,643
-
6But 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 01:47
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 ]
.)
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.

- 217

- 105,154
- 20
- 279
- 497
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.

- 102,282
-
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 topgrep firefox || echo "Firefox not running"
, although more readable and allows more commands – Sergiy Kolodyazhnyy Jul 13 '18 at 02:24
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).
....

- 111
glenn jackman's answer above is correct, but here is a detailed explanation of what this operator does:
Prevents the result from being run as a command
Essentially the null operator :
prevents the result of a parameter expansion from being run as a command.
Here is a step-by-step explanation of how this works.
Run a command in bash
# Runs 'curl'
curl
Define variables and run them as commands in bash
# Define variables
EXISTING_COMMAND=curl
EMPTY_COMMAND=
Runs the 'curl' command with no flags or arguments
${EXISTING_COMMAND}
Runs the empty command, effectively doing nothing
${EMPTY_COMMAND}
Reassign a variable if empty, then run it as a command
# Define variables
EMPTY_COMMAND=
Assigns 'curl' to the EMPTY_COMMAND variable, then runs 'curl'
${EMPTY_COMMAND:=curl}
Runs 'curl'
${EMPTY_COMMAND}
You don't have to pass a literal as the default. You can also use a parameter expansion, as in ${EMPTY_COMMAND:=${EXISTING_COMMAND}}
Perform an empty-coalesce chain on a variable
TARGET_VAR=
OPTION_A=
OPTION_B=
Skips OPTION_A and OPTION_B since they are empty too, then assigns 'curl'
: ${TARGET_VAR:=${OPTION_A:=${OPTION_B:=curl}}}
I do not recommend this since both OPTION_A
and OPTION_B
will be overwritten with curl
as well.
Do NOT run a variable as a command
# Define variables
EXISTING_COMMAND=curl
Doens't do anything
: ${EXISTING_COMMAND}
Reassign a variable if empty, then do NOT run it as a command
# Define variables
EXISTING_COMMAND=curl
EMPTY_COMMAND=
Assigns 'curl' to the EMPTY_COMMAND variable
: ${EMPTY_COMMAND:=${EXISTING_COMMAND}}
echo's 'curl' as text
echo ${EMPTY_COMMAND}
:
always returns 0
:
As pointed out by several answers above, then :
operator, when thought of as a command, will always return 0
, which effectively evaluates to true when used as a conditional expression.
In general, commands conditionally return 0
to indicate successful execution, or any positive number, such as 1
, to indicate that an error has occured.
Curl returning a positive value without flags and/or arguments
# Runs 'curl', then echo's 'False'
if curl ; then
echo 'True'
else
echo 'False'
fi
Curl returning 0
value with valid flags and arguments
# Runs 'curl --version', then echo's 'False'
if curl --version ; then
echo 'True'
else
echo 'False'
fi
:
returning 0
value with valid flags and arguments
# Runs ':', then echo's 'True'
if : ; then
echo 'True'
else
echo 'False'
fi

- 101
- 3
-
Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center. – Community Mar 24 '23 at 17:30