15

I'm new to shell scripting and I came across these expressions

${var:-val} and ${var-val}

${var:+val} and ${var+val}

${var:=val} and ${var=val}

so how are they evaluated and what are the differences between them

Rui F Ribeiro
  • 55,929
  • 26
  • 146
  • 227
WLION
  • 295
  • 1
  • 6

1 Answers1

12

These are all various forms of parameter expansion with alternatives:

  • ${var:-val} is replaced by val if var is unset or null, ${var} otherwise (so val is a "default value");
  • ${var:=val} first assigns val to var if var is unset or null, and then (in all cases) is replaced by ${var};
  • ${var:+val} is replaced with nothing if var is unset or null, val otherwise.

Omitting the : drops the "or null" part of all these definitions.

This is all described in the bash(1) manpage, and in POSIX.

Some examples might help:

unset a
echo "${a:-default}"

produces default, as does echo "${a-default}".

a=
echo "${a:-default}"

again produces default, but echo "${a-default}" outputs a blank line.

a=test
echo "${a:-default}"

produces test, as does echo "${a-default}".

unset a
echo "${a:=default}"

produces default, and a is now default (as confirmed by echo "${a}").

The + form might seem strange, but it is useful when constructing variables in several steps:

PATH="${PATH}${PATH:+:}/blah/bin"

will add : before /blah/bin only if PATH is non-empty, which avoids having a path starting with :.

Stephen Kitt
  • 411,918
  • 54
  • 1,065
  • 1,164
  • 1
    The `:+` form is also useful for avoiding placing the empty string as an argument on a command line, while still properly double-quoting the variable. e.g. `grep ${ignorecase:+"$ignorecase"} ... `. The other, worse, alternative is to just use `$ignorecase` unquoted on the cmd line...which is only safe if you know **exactly** what `$ignorecase` can contain. – cas May 30 '16 at 12:47