views:

216

answers:

4

The question says it: what would be the purpose of a command that does nothing, being little more than a comment leader, but actually a shell built-in in and of itself.

It's slower than inserting a comment into your scripts, by about 40% per call, which probably varies greatly on the size of the comment. The only possible reasons I can see for it are these:

# poor man's delay function
for ((x=0;x<100000;++x)) ; do : ; done

# inserting comments into string of commands
command ; command ; : we need a comment in here for some reason ; command

# an alias for `true' (lazy programming)
while : ; do command ; done

Edit: I guess what I'm really looking for is what historical application it might have had.

+7  A: 

Historically, Bourne shells did have neither true nor false as builtins. true was instead simply aliased to :, and false to something like let 0.

Nowadays, the primary reasons for using : are for needing scripts to be portable to ancient versions of Bourne-derived shells. As a simple example, now-ancient versions of the Korn shell (ksh88) did not have a ! command (for negating the exit code).

Thus if you want to portably (across Bourne-derived shells) check for failed execution of a command, you could use:

if command; then :; else ... fi

Note that if requires a non-empty then clause, and comments do not count as non-empty.

As an aside on the insanity that is portable shell scripts: for maximum portability, using : is in fact safer than using true. Modern systems typically have a true binary which will be used as a fall-back, if the shell happens to not have this builtin. But in the worst case, neither builtin nor binary exist, and then attempting to execute true will result in a "command not found" error. This, in turn, typically also leads to an exit code != 0, exactly the opposite of what was intended!

earl
Of course, but as I hinted at, there can be reasons to prefer the round-about variant. Typically, it's about portability. For example, ancient Korn shells (ksh88) have the `:` builtin, but no `!`.
earl
(Updated the answer to incorporate this historic perspective.)
earl
Wow, this covers a lot. Thanks for the history lesson! :-)
amphetamachine
+1  A: 

You could use it in conjunction with `` to execute a command without displaying its output, like this:

: `some_command`

Of course you could just do some_command > /dev/null, but the :-version is somewhat shorter.

That being said I wouldn't recommend actually doing that as it would just confuse people. It just came to mind as a possible use-case.

sepp2k
This is not safe if the command is going to dump a few megabytes of output, since the shell buffers the output and then passes it as command-line arguments (stack space) to ':'.
Juliano
+2  A: 

It's similar to pass in Python.

One use would be to stub out a function until it gets written:

future_function () { :; }
Dennis Williamson
+1  A: 

I use it to easily enable/disable variable commands:

#!/bin/bash
if [[ "$VERBOSE" == "" || "$VERBOSE" == "0" ]]; then
    vecho=":"     # no "verbose echo"
else
    vecho=echo    # enable "verbose echo"
fi

$vecho "Verbose echo is ON"

Thus

$ ./vecho
$ VERBOSE=1 ./vecho
Verbose echo is ON

This makes for a clean script. This cannot be done with '#'.

Also,

: >afile

is one of the simplest ways to guarantee that 'afile' exists but is 0 length.

Kevin Little
`>afile` is even simpler and achieves the same effect.
earl
@earl is right; I've edited my answer accordingly.
Kevin Little