Shell script ending with a line containing only a colon?
Asked Answered
P

2

6

I'm studying System V init scripts found in /etc/init.d/ in current Debian 7.4.0 wheezy release(But its also present in other, previous, releases). Almost all of them (from existing services) found in that folder end with, basically an empty line containing nothing but a colon (:) sign. Even the 'skeleton' template file that can be found there for the purpose of writing your own init scripts has this. Here is a copy/paste from the end of the code:

esac

:

(that was the end of an case statement and then there is the end of the file)

What is also interesting is that there is no exit 0 or exit $? call, except only in some conditions in the case statement, that would be called otherwise so it seems as if that colon sign is a sort of a replacement for it? Full skeleton file code is here: https://gist.github.com/ivankovacevic/9917139

What could that colon be and why?

Preamplifier answered 1/4, 2014 at 14:28 Comment(1)
: is a builtin which evaluates to true in bash, so I suspect this is to reset $? to 0.Goodwin
R
5

The colon is a syntactic element that, essentially, does nothing, but returns true. It can be used whereever a command can be used.

It is sometimes needed where sh(1) requires a statement. E.g., this gives an error:

if [ "$a" = "" ] ; then
  # comment out this part for now
  # echo yes
else
  echo no
fi

bash: syntax error near unexpected token `else'

Replacing the comment with a : makes it work:

if [ "$a" = "" ] ; then
  # comment out this part for now
  : echo yes
else
  echo no
fi

It is rarely needed to explicitly use "exit 0" in the shell; in the absence of an exit statement, the shell script exits with the status of the last command, a shell script that just executes

/bin/false

will give an exit status 1:

$ echo $?
1

The colon is largely black magic, and I learned what little I know about it from experimentation.

Reneerenegade answered 1/4, 2014 at 14:41 Comment(4)
why not call exit 0 at the end of the script, instead of screwing with peoples mind with a : ... Or is there any real benefit in using a colon over exit 0Preamplifier
I agree @Ivan Kovacevic: readability is improved by being explicit about the exit value, so I always write "exit 0" when I need a script to return a success status.That said, one should only use 'exit 0' when one actually wants to override an error status, because error status returns are there for a reason.Reneerenegade
The colon has one arguable benefit: it produces an exit status of 0 without having to choose between exit and return (useful if a script might be executed or sourced; exiting from a sourced file is unlikely to be desirable and returning from a script is an error). These days, the more readable true should be available in place of the archaic : for this purpose.Ly
@chepner: That is really a reasonable case! In my mind your comment could qualify as a full answer to this.Preamplifier
E
1

The : returns true status in BASH and is just a replacement for the word true. I don't see any benefit to using : as apposed to exit 0 at the end of a system init script other than to save characters or make it less readable.

As chepner point's out, : would ensure a true status without exiting the shell if the script is sourced.

It is also commonly used to replace logical negation using ! in statements.

if [[ $var ]]; then
    :
else
    echo no
fi

Is the same as:

if ! [[ $var ]]; then
    echo no
fi
Ebbie answered 1/4, 2014 at 15:24 Comment(1)
If the script can (or must) be sourced, exit 0 will exit the shell that sourced the script, not just the script.Ly

© 2022 - 2024 — McMap. All rights reserved.