logo
Kurashizu Blogwhere ideas flow
  • Home
  • News
  • Blog
  • About
  • Home
  • News
  • Blog
  • About

© 2026 Kurashizu. All rights reserved.

Admin·New Post·Service Status
Powered by Cloudflare·01.11.26
← Back to news

A shell colon does nothing. Use it anyway

Original article
refp.se|342 points|148 comments|by olexsmir|Jul 25, 2026

The Power of Nothing: Why the Shell Colon is Actually Useful

I have authored a countless number of shell scripts over the years, yet I am still frequently blindsided by simple tricks that leave me wondering how I didn't know them sooner.


Metadata

PublishedModifiedAuthorTags
23 July 202626 July 2026Filip Roséen#shell, #posix, #unix

☕ A Scene from the Digital Trenches

Imagine this: a desk featuring a cup of coffee that has gone ice-cold sitting right next to a fresh brew that is far too hot to drink. There are four different terminal windows open—three of which should have been killed an hour ago—and a shell script that I was dreading having to write.

In the midst of this chaos, I discovered that a single character—the colon (:)—could save my night.


🛡️ Validating Mandatory Arguments

Most of us have a "muscle memory" approach to checking if a script received the necessary inputs. Usually, it looks like this:

if [ -z $1 ]; then echo "missing argument, aborting"; exit 1; fi

But what if you could condense those four lines into a single, elegant expression?

# Example: example.sh
: ${1:?missing argument, aborting.}

The Result: $ bash example.sh example.sh: line 1: 1: missing argument, aborting.

If you use a named variable instead of a positional parameter, the diagnostic becomes even clearer because the shell includes the variable's name:

# greet.sh
: ${GREET_NAME:?missing argument, aborting.}
echo "Hello $GREET_NAME!"

$ bash greet.sh greet.sh: line 1: GREET_NAME: missing argument, aborting.

How it Works

There are two distinct mechanisms interacting here:

  1. Parameter Expansion: The syntax ${name:?diagnostic} checks if a variable is either unset or null.
    • If empty/unset →\rightarrow→ print the diagnostic to stderr and exit with a status ≠0\neq 0=0.
    • If set →\rightarrow→ it simply expands to the value of the variable.
  2. The Null Command: The leading colon.

🔍 What exactly is the "Other" Colon?

You might be wondering about the colon sitting at the start of the line.

The : is known as the null-command. It is a shell builtin that evaluates all its arguments and then promptly throws the result away. It is an ancient relic, dating back to the 1971 Thompson shell, where it served a dual purpose as both a label and the original Unix comment marker.


🚀 The Null-Command in the Limelight

To demonstrate that the null-command is more than just a placeholder, consider these mind-blowing applications:

  • Setting Defaults: : ${DATA_DIR:=/var/data} (The colon swallows the result of the assignment).
  • Default Retries: : ${RETRIES:=3}.
  • File Truncation: : error.log (Truncates the file).
  • Multi-file Truncation: : error.log access.log.
  • Readability Check: ( : dataset.json ) echo YES (Checks if the file is readable).
  • Interrupt Handling: trap : INT (Since trap requires a command, : provides a no-op).
  • Unset Variable Validation:
    set -u # Treat unset variables as errors
    : $DEPLOY_ENV $HOST # Validates existence without executing them
    
  • Filling Logic Gaps:
    if some-command; then 
        : # A command is required here, but we want nothing to happen
    else 
        echo "command failed" 
    fi
    

🏁 Con-colon-sion

If you share my desire to minimize keystrokes (because we've got to go fast), the combination of the null-command and parameter expansion is a powerful duo.

Try this safe local experiment:

set : : : : : : : : : : : : : : : : : : : : : 
while : colons are more than ${1:?magic} ; do 
    echo $* 
    shift 
done

❓ Frequently Asked Questions

Why do I need the null-command for parameter expansion?

If you omit the colon, the shell evaluates the expansion and then tries to execute the resulting string as a command.

# Without the colon:
% ${HELLO:=123} 
zsh: command not found: 123 

# With the colon:
% : ${HELLO:=123} 
% echo $HELLO 
123

Why use : ${VAR:=val} instead of VAR=${VAR:-val}?

This is largely a matter of preference, but the colon method reduces the chance of typos by mentioning the variable name only once.

MethodVariable MentionsRisk
: ${DATA_DIR:=/var/data}1Low
DATA_DIR=${DATA_DIR:-/var/data}2Higher (e.g., DATA_DIR=${DATA_DRI:-...})

Doesn't this hurt readability?

Some argue that using : in an if statement is contrived. For example, one could simply use if ! some-command. However, the goal of that example isn't to suggest that you should always use it in if blocks, but to illustrate that whenever a command is syntactically required but no action is desired, the null-command is your tool.


🌍 Real-World Application: The Git Trick

A user named ifphilipe on Hacker News shared a brilliant use case for the null-command:

I use the colon as EDITOR with Git when I want to do an interactive rebase combined with auto squash without having to edit the todo list.

I have an alias for that which I call a quick interactive rebase: alias riq='git -c sequence.editor=: rebase --interactive'

Reflection: While the if statement example in this article was debated, this Git alias is a perfect, practical example of needing a command that does absolutely nothing.

Final Checklist for Shell Mastery

  • Understand ${VAR:?msg}
  • Recognize the : null-command
  • Apply : ${VAR:=val} for defaults
  • Use EDITOR=: to skip Git edits