[sf-lug] a good reason for putting the : command in a shell script?

Michael Paoli Michael.Paoli at cal.berkeley.edu
Fri Mar 7 20:24:36 PST 2008


Quoting jim stockford <jim at well.com>:

>     what is a good reason for putting the  :  command
> in a shell script?

The : command is exceedingly handy and concise when one wants to be
assured of efficiently having a true (0) return status - either at that
particular point in the script execution, for whatever reason(s), or
for having the script exit 0.

Here are some fairly typical examples, first from a hypothetical
crontab job:
37 0 * * * >>/dev/null 2>&1 some_command; :
Let's say we aren't particularly interested in the stdout or stderr of
some_command when it's run as our crontab job.  Let's say also we're
not concerned about its exit value.  However, most cron systems will
note or log non-zero exit returns of crontab jobs as an error/failure -
in many environments - e.g. production, this may trigger alarms/alerts
... and in this case we may not want that effect (or just want our logs
to look cleaner, as we don't care about the exit value of some_command
in this case).

Glancing over a small selection of my shell scripts at my fingertips:
while :
Have a while loop?  Always want it to start before testing any explicit
condition?  Perhaps want it to do a "test at the bottom" - or in the
middle, or maybe it runs "forever" - at least until some other
condition stops it?  Start with while :.

for configfile in "$HOME"/.fetchyahoorc*
do
    if [ -f "$configfile" ]; then
        fetchyahoo --configfile="$configfile"
    else
        :
    fi
done

In the above, as we iterate over what we got from our shell globbing
attempt, if a result fails the ordinary file test, we successfully do
nothing with it, and that pass of the if statement then returns zero.
If we didn't have that else : in there, in that particular case, our if
statement would return the non-zero value it got from the test - and if
that was the last pass of our for loop, then the for loop would return
that non-zero value.

Perhaps we want to do nothing (successfully) in a case statement if a
certain pattern matches, and take some other action otherwise:
case "$foo" in
    *bar*)
        :
    ;;
    *)
        echo 'No bar? '
    ;;
esac
In the above, the syntax of the case statement requires a list (one or
more pipelines or simple commands) between our pattern and ;;, so in the
above case we use the concise and efficient :.

Linux(/Unix/BSD/...) convention with commands is they return 0 when
"successful" (for some suitable definition of "successful") and
non-zero otherwise.  This allows very powerful commands to be built up,
by use of conditionals and command flow, and nesting of various
commands, programs and scripts, etc., in relatively arbitrarilly
complex and deep manners.  For those things to generally work properly,
the convention needs to be followed appropriately - and that means that
scripts/programs should follow the appropriate convention, and exit 0
when "successful" and non-zero otherwise.




More information about the sf-lug mailing list