Cached at:
07/25/26, 12:03 PM
# A shell colon does nothing. Use it anyway.
Source: [https://refp.se/articles/your-shell-and-the-magic-colon](https://refp.se/articles/your-shell-and-the-magic-colon)
I've written more shell scripts than I can count, but I still stumble upon tricks that honestly blow my mind far too often than I care to admit\. Latest thing that blew my head clean off? The shell colon\.
Published23 July 2026 at 03:53 UTCAuthorTags- [\#shell](https://refp.se/articles/tagged/shell)
- [\#posix](https://refp.se/articles/tagged/posix)
- [\#unix](https://refp.se/articles/tagged/unix)
## In a land far\-far away\.\.
\.\.\. there was once a far too cold cup of coffee next to a freshly brewed far\-too\-hot one\. Four different terminals where three could have been closed an hour ago, and a shell script which I really \(really\) did not want to write\.
Who would have thought a single colon would be the one to save the`day`night?
> **Note**: Want your mind blown straight away? See[Other colons worth remembering](https://refp.se/articles/your-shell-and-the-magic-colon#other-colons-worth-remembering)\.
## Checking for required arguments
This is a familiar dance, it's pretty much muscle memory by this point\. You have a script, it takes a few arguments, and some of them are mandatory; alright, an if\-statement like so many times before:
```
if [ -z "$1" ]; then
echo "missing argument, aborting!" 1>&2
exit 1
fi
echo "Hello $1!"
```
Though\.\. what if I told you the above four lines could be replaced by just\.\.\. one?
```
: "${1:?missing argument, aborting!}"
echo "Hello $1!"
```
```
$ bash example.sh
example.sh: line 3: 1: missing argument, aborting!
$ bash example.sh refp
Hello refp!
```
### Parameter expansion and the story of`:?`
There are two things going on in the previous snippet, and you are correct in identifying that one part is using[parameter expansion](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02):
- The syntax`$\{name:?diagnostic\}`checks whether`$name`is unset or empty — if it is, the diagnostic is printed to*stderr*and the shell exits with a non\-zero status, otherwise;
- if the variable is set, it is equivalent to`$name`\.
## That\.\. other colon
So that's one colon, but what about that other one, the one who sits alone at the beginning of the line?
- `:`is the[null command](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_16)— a builtin that does nothing but evaluate its arguments and discard the result\.
- `:`is old — it goes all the way back to the[1971 Thompson shell](https://en.wikipedia.org/wiki/Thompson_shell#Design)where it doubled as a[label](https://www.in-ulm.de/~mascheck/bourne/PWB/goto.1.html)and Unix's very first comment marker\.
- `:`two eyes staring at you in the dark, with love\.
## Other colons worth remembering
Perhaps we have already established that there is more to`:`than meets the eye, but to prove the real magic of the[null\-command](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_16)— here are a few usages that blew my mind\.
```
: "${DATA_DIR:=/var/data}" # set defaults, : swallows the result
: "${RETRIES:=3}" # instead of running it as a command
```
```
: > error.log # truncate error.log
: > error.log > access.log # truncate both error.log and access.log
```
```
( : < dataset.json ) && echo YES # is dataset.json readable?
( : >> result.json ) && echo YES # is result.json writable?
```
```
trap : INT # trap requires a command
sleep 60 # sleep is interruptible
```
```
set -u # error on unset variables
: "$DEPLOY_ENV" "$HOST" # check DEPLOY_ENV and HOST
```
## Con\-colon\-sion
So, if you are like me and prefer less typing \(gotta go fast\) — the[null command](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_16)and[parameter expansion](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02)are a good pair to remember\.
```
while : colons are more than punctuation; do
echo "I love colons"
sleep 1
done
```