A shell colon does nothing. Use it anyway

Lobsters Hottest Tools

Summary

Explains the shell colon (null command) and its practical uses like argument checking, setting defaults, and file operations.

<p><a href="https://lobste.rs/s/eidh3u/shell_colon_does_nothing_use_it_anyway">Comments</a></p>
Original Article
View Cached Full Text

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 ```

Similar Articles

POSIX Is Not a Shell

Hacker News Top

This article argues that POSIX is a specification, not a program, and that shell implementations such as bash and dash behave differently even for basic commands like echo. It calls for testing across multiple shells rather than relying on the notion of 'POSIX compliance' for portability.

Nul Characters in Strings in SQLite

Hacker News Top

SQLite allows NUL characters in strings but this can cause unexpected behavior in string functions and CLI output; the page explains how to detect and remove embedded NULs.

A tale of two path separators (2021)

Lobsters Hottest

Explains how macOS handles two path separators (slashes and colons) due to its dual heritage from classic Mac OS and NeXTSTEP, and how this leads to files appearing with slashes in Finder but colons in the terminal.

Odd Comments and Strange Doings in Unix

Lobsters Hottest

Dennis Ritchie recounts quirky error messages and comments from early Unix source code, including the famous 'values of β will give rise to dom!' and the unlikely comment 'You are not expected to understand this.'