It's all explained in the Shell Parameter Expansion section of the manual:
${parameter:-word}
If parameter
is unset or null, the expansion of word
is substituted. Otherwise, the value of parameter
is substituted.
Just before this there is:
Omitting the colon results in a test only for a parameter that is unset.
So:
${X-stuff}
expands to:
- The expansion of
$X
if X
is set
stuff
if X
is unset.
Try it:
$ unset X
$ echo "${X-stuff}"
stuff
$ X=
$ echo "${X-stuff}"
$ X=hello
$ echo "${X-stuff}"
hello
$
Now your expansion is
${X-}
so you guess that it expands to the expansion of $X
if X
is set, and to the null string if X
is unset.
Why would you want to do this? to me it seems that this is a workaround the set -u
:
$ set -u
$ unset X
$ echo "$X"
bash: X: unbound variable
$ echo "${X-}"
$
Finally, your test
if [ -z "${X-}" ]
(note the quotes, they are mandatory) tests whether X
is nil (regardless of X
being set or not, even if set -u
is used).
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…