Why You Should Use the Shell Colon Even Though It Does Nothing

A shell colon does nothing. Use it anyway

Why You Should Use the Shell Colon Even Though It Does Nothing

I recently discovered how the shell colon, a command that technically does nothing, can dramatically simplify my scripts. By combining the null command with parameter expansion, I can validate arguments, set default values, and check file permissions in a single, safer line of code. This ancient Unix trick reduces typing errors and keeps my shell scripts clean and efficient without needing complex if-statements.

Two eyes staring at you in the dark, with love.
  1. teddyh

    I once created a set of shell functions which I wanted to have a docstring-like functionality. The solution I came up with was to have each shell function start with the : command with a string as an argument. Since : is an actual command, not a comment, it was preserved as part of the function, and could be extracted at runtime using relatively simple parsing to do introspection.

    Example:

    foo(){

    : "This is a docstring for the foo() function"

    bar --verbose | baz --quiet

    }

    (Repost of <https://news.ycombinator.com/item?id=29152308>)

  2. garethrowlands

    Articles like this are fun but they all come from posix shell syntax being fundamentally bad for scripting/programming. All the piping stuff is great, of course. And the overall ecosystem is great. But the interpretation of the script itself working by a series of string substitutions is a mechanism we wouldn't accept in a regular programming language. And there's no excuse for it really, except that shell syntax is really, really old.

    For example, what does `$foo` mean in shell syntax? In any reasonable language (perl or powershell, for example, or python if you drop the `$`), it's an expression that evaluates to whatever value's inside that variable. In shell, `$foo` isn't an expression in that sense, and what it does depends on what's inside it via a variety of string substitution rules.

    This is the main reason we have arcane articles like this.

    That said, nice article.

  3. amiga386

    Well that's exciting. I learned a lot of uses for ":" today.

    However, the only one I already knew...

    if some-command; then

    : # command required

    else

    echo "command failed"

    fi

    I used to do that until I learned of

    if ! some-command; then

    echo "command failed"

    fi

    It's in the POSIX standard so it's not just a bashism: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V...

    > If the pipeline does not begin with the "!" reserved word, the exit status shall be the exit status of the last command specified in the pipeline. Otherwise, the exit status shall be the logical NOT of the exit status of the last command

  4. fphilipe

    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[1] for that which I call a quick interactive rebase:

    riq = -c sequence.editor=: rebase --interactive

    [1]: https://github.com/fphilipe/dotfiles/blob/94f2ff70bade070694...

  5. kevincox

    I am not a huge fan of most of these, but a few do seem useful.

    : "${1:?missing argument, aborting!}"

    I wouldn't use this because I would want to give $1 a name for the rest of the script, so I would assign. But it can be a nice way to give a clear error for missing required environment variables.

    Many of the others (like truncating files) are probably more clearly written with dedicated commands, but may come in useful if you are going to extreme lengths to avoid dependencies outside of the shell.

  6. dominiwe

    I actually did absolutely need it recently when I golfed together a shell script that is simultaneously a valid YAML file [0]. Sometimes having no-op tokens is nice!

    [0]: https://domi.work/blog/posts/compose_polyglot/

  7. c0l0

    My personal favourite use of the colon command is what I've written about some years ago: https://johannes.truschnigg.info/writing/2021-12_colodebug/

  8. archargelod

    Why take a perfectly readable if-statement and turn it into something, 99.9% of people would need to lookup. Concise != better. You can make it one line with:

    [ -z "$1" ] && { echo "missing argument, aborting." 1>&2; exit 1 }

More from this day

2026-07-26