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
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Sign up to join this communityThese 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 :
.
:+
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.