Bernhard R. Link: The Colon in the Shell.
I was recently asked about some construct in a shell script starting with a colon(:), leading me into a long monologue about it. Afterwards I realized I had forgotten to mention half of the nice things. So here for your amusement some usage for the colon in the shell:
To find the meaning of ":" in the bash manpage[1], you have to look at the start of the SHELL BUILTIN COMMANDS section. There you find:
: [arguments] No effect; the command does nothing beyond expanding arguments and performing any specified redirections. A zero exit code is returned.If you wonder what the difference to true is: I don't know any difference (except that there is no /bin/:) So what is the colon useful for? You can use it if you need a command that does nothing, but still is a command.
-
For example, if you want to avoid using a negation (for fear of history expansion still being on by default on a interactive bash or wanting to support ancient shells), you cannot simply write
if conditon ; then # this will be an error else echo condition is false fi
but need some command there, for which the colon can be used:if conditon ; then : # nothing to do in this case else echo condition is false fi
To confuse your reader, you can use the fact that the colon ignores it's arguments and you only have normal words there:if conditon ; then : nothing to do in this case # <- this works but is not good style else echo condition is false fi
though I strongly recommend against it (exercise: why did I use a # there for my remark?). -
This of course also works in other cases:
while processnext ; do : done
-
The ability to ignore the actual arguments (but still processing them as with every command that ignores it arguments) can also be used, like in:
: $ VARNAME:=default
which sets VARNAME to a default if unset or empty. (One could also use that the first time it is used, or $ VARNAME:-default everywhere, but this can be more readable). -
In other cases you do not strictly need a command, but using the colon can clear things up, like creating or truncating a file using a redirection:
: > /path/to/file
- misuing it for comments:
: ====== here
While it has the advantage of also showing up in -x output, the to be expected confusion of the reader and the danger of using any shell active character makes this general a bad idea. -
As it practically the same as true it can be used as a shorter form of true. Given that true is more readable that is a bad idea. (At least it isn't as evil as using the empty string to denote true.)
# bad style! if condition ; then doit= ; doit2=: ; else doit=false ; doit2=false ; fi if $doit ; then echo condition true ; fi if $doit2 && true ; then echo condition true ; fi
- Another way to scare people:
ignoreornot= $ignoreornot echo This you can see. ignoreornot=: $ignoreornot echo This you cannot see.
While it works, I recommend against it: Easily confusing and any > in there or $(...) will likely rain harvoc over you. - Last and least, one can shadow the built-in colon with a different one. Only useful for obfuscation, and thus likely always evil. :() :&: ;: anyone?