What does ${PATH:+:${PATH}} mean?
The :+
is a form of parameter expansion:
${parameter:+[word]} : Use Alternative Value.
If parameter is unset or null, null shall be substituted; otherwise, the expansion of word (or an empty string if word is omitted) shall be substituted.
In other words, if the variable $var
is defined, echo ${var:+foo}
will print foo
and, if it is not, it will print the empty string.
The second :
is nothing special. It is the character used as a separator in the list of directories in $PATH
. So, PATH="/usr/local/bin:/usr/bin${PATH:+:${PATH}}"
is a shorthand way of writing:
if [ -z "$PATH" ]; then
PATH=/usr/local/bin:/usr/bin
else
PATH=/usr/local/bin:/usr/bin:$PATH
fi
It's just a clever trick to avoid adding an extra :
when $PATH
is not set. For example:
$ PATH="/usr/bin"
$ PATH="/new/dir:$PATH" ## Add a directory
$ echo "$PATH"
/new/dir:/usr/bin
But if PATH
is unset:
$ unset PATH
$ PATH="/new/dir:$PATH"
$ echo "$PATH"
/new/dir:
A :
by itself adds the current directory to the $PATH
. Using PATH="/new/dir${PATH:+:$PATH}"
avoids this. So sure, you can use PATH="${PATH:+${PATH}:}/usr/local/bin:/usr/bin"
if you want to, or you can use PATH="$PATH:/usr/local/bin:/usr/bin"
if you prefer. The only difference is that the former might add an extra :
, thereby adding your current directory to your $PATH
.
You're correct, it does mean 'if $PATH exists — and is not null — then add :$PATH'.
You need to check whether $PATH exists because you don't want to add the leading (or trailing) colon if $PATH is undefined. A zero-length (null) directory name in the path, as in :/usr/local/bin:/usr/bin
, or /usr/local/bin:/usr/bin:
, or /usr/local/bin::/usr/bin
, means search the current directory.
Excerpted from man bash
:
PATH ...
A zero-length (null) directory name in the value of PATH indicates
the current directory. A null directory name may appear as two
adjacent colons, or as an initial or trailing colon.
...
That's probably not what you want to do.
The following two lines do the same thing:
PATH=":/bin" # search current directory, then /bin
PATH=".:/bin"