Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I've hacked on a lot of shell scripts, and sometimes the simplest things baffle me. Today I ran across a script that made extensive use of the : (colon) bash builtin.

The documenation seems simple enough:

: (a colon)  
     : [arguments]  

Do nothing beyond expanding arguments and performing redirections. The return status is zero.

However I have only previously seen this used in demonstrations of shell expansion. The use case in the script I ran across made extensive use of this structure:

if [ -f ${file} ]; then
    grep some_string ${file} >> otherfile || :
    grep other_string ${file} >> otherfile || :

There were actually hundreds of greps, but they are just more of the same. No other input/output redirects are presentother than the simple structure above. No return values are checked later in the script.

I am reading this as a useless contstruct that says "or do nothing". What purpose could ending these greps with "or do nothing" serve? In what case would this construct cause a different outcome than simply leaving off the || : from all instances?

share|improve this question
One possible purpose I can see is to use : as an alternative to true. Perhaps errexit is set and the author doesn't care about the exit status of some commands. – jw013 Feb 14 '12 at 18:42
Heh, nearly identical question on SO – jw013 Feb 14 '12 at 18:49
up vote 17 down vote accepted

It appears the :s in your script are being used in lieu of true. If grep doesn't find a match in the file, it will return a nonzero exit code; as jw013 mentions in a comment, if errexit is set, probably by -e on the shebang line, the script would exit if any of the greps fail to find a match. Clearly, that's not what the author wanted, so (s)he added || : to make the exit status of that particular compound command always zero, like the more common (in my experience) || true/|| /bin/true.

share|improve this answer
Duh. This was in the concept of an RPM build script, and while I didn't see any exit code checking inside the script, I forgot to consider that the parent process might be watching. – Caleb Feb 14 '12 at 20:55
If that's the case, I'd call it poor scripting practice. It's functionally equivalent to using true instead, but the semantic intent is much clearer with true. : is more suitable when an explicit NOP is desired. – jw013 Apr 27 '12 at 6:12

The : builtin is also useful with the Bash "assign default values" shell expansion, where the expansion is often used solely for the side effect and the value expanded is thrown away:

# assign FOO=bar iff FOO is unset
: ${FOO:=bar}
share|improve this answer
Came here looking for this, was baffled when I saw this pattern in a script to declare default values. – ffledgling Jun 18 '15 at 10:33

I can think of two places I've used : in the past.

while :
     shell commands
     some exit condition

That is a forever-loop.

function doSomethingStub {

Put in a stub function, just to get top level flow of control correct.

One use I've seen back in the Old Days: Instead of a #!/bin/sh (or whatever) line, you'd see a : line. Some of the older Real Unix kernels or Real Unix shells would use that to mean "I'm a shell script, have sh run me". As I recall this was just when csh was making inroads as a common interactive shell.

share|improve this answer
+1 for older than the shebang usage – Arcege Feb 14 '12 at 22:46
@BruceEdiger: Do you have a reference to the "shecolon" line? – l0b0 Mar 22 '12 at 8:20
Finally found a ": at the beginning of a script" reference and explanation: faqs.org/faqs/unix-faq/faq/part3/section-16.html – Bruce Ediger Mar 22 '12 at 20:22

The : built-in was already in the Thompson shell — it's documented for Unix V6 in 1975. In the Thompson shell, : indicated a label for the goto command. If you never attempted to call goto on a line beginning with , that line was effectively a comment.

The Bourne shell, the ancestor of Bourne/POSIX shells as we know them, never had a goto that I know of, but retained : as a no-op command (it was already present in Unix V7).

share|improve this answer

I seem to recall that early versions of the shell didn't have a comment syntax. A line starting with : (which probably would have been an actual executable, similar to /bin/true) would have been the best alternative.

Here's a man page for the ancient Thompson shell (no relation); there's no mention of any comment syntax.

share|improve this answer
The origin of : was in fact a label indicator for the goto command, in some ancient shell (I don't know which). A label : something could indeed be used as a comment, if there was no matching goto. The practice stuck even after goto disappeared. – Gilles Feb 15 '12 at 6:29

Dug out an old reference: "The UNIX Programming Environment" (c) 1984 by Kernighan and Pike.

Page 147 (Shell Programming) says this:

":" is a shell built-in command that does nothing but elevate its arguments and return "true". Instead [referring to a script example], we could have used true, which merely returns a true exit status. (There is also a false command.) But ':' is more efficient than true because it does not execute a command from the file system. [Italics/emphasis is mine.]

share|improve this answer

":" is handy for debugging.

DEBUGLOG=": debugfunction"

$DEBUGLOG arg1 arg2 ...

Running normally the debugfunction is never executed so sh just steps over the noop (variables and wildcards are expanded though). If more in depth debugging is required, remove the noop from the variable and debugfunction is called with whatever arguments are required.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.