Following is a simple shell script to demonstrate how environment variables are accessible.

if [[ ${x+X} = X ]] ## If $x is set
  if [[ -n $x ]] ## if $x is not empty
    printf " \$x = %s\n" "$x"
    printf " \$x is set but empty\n"
  printf " %s is not set\n" "\$x"

However, I had the following doubts with regards to the first "if condition".

  1. Inside the [[ operator a single "=" is used for comparison.But isn't = an assignment operator ?
  2. Could you please explain "${x+X}" works in this script ?
  • Where did you get your example? – David King Dec 22 '15 at 19:43
  • 1
    man bash will explain = for [[ under "CONDITIONAL EXPRESSIONS". And, I suspect your example should say ${x:+X} instead. That's under Parameter Expansion. – Jeff Schaller Dec 22 '15 at 19:50
{   unset x
    echo ${x+"you won't see this"}
    echo ${x+"this you'll see"} ${x:+"and this you won't"}
    echo ${x+"now you'll"} ${x:+"see it all"}

this you'll see
now you'll see it all

Practically all of the basic POSIX parameter expansions behave differently when the expanded parameter is either unset or null depending on the : optional colon modifier.

The + form of parameter expansion expands to word when the parameter is set regardless of its contents in the expansion:


However, it does not expand to word when $parameter is set but null in the following:


There are also the expansion forms for -, =, and ?. The - will expand to word when $parameter is unset, or, with :, when it is either unset or null. The = will expand identically as -, except that it will also set the null or unset $parameter's value to word. And ? kills a shell while writing an optional word error message to stderr when $parameter is unset, or, with :, of null value. For any of these three, if the $parameter is set, and, with :, is not null, then $parameter expands to its value just as it would otherwise.


Isn't = an assignment operator?

Yes, it is, and it is also a comparison operator, depending on where it appears: as in many languages, meaning of tokens depends on context. Bash supports both assignment, in the form name=[value], and comparison using the expressions languages for test (also known as [) and [[; within those, = has a different meaning.

What is ${x+X}?

Bash supports the syntax ${parameter:+word}:

Use Alternate Value. If parameter is null or unset, nothing is substituted, otherwise the expansion of word is substituted.

In your case, this means that, if x is unset, then the expression will expand to the empty string (the comparison with X will fail), and, if it is set, it will expand to X (the comparison will yield true).

The syntax ${parameter+word} is a variation of ${parameter:+word}, with a slight difference, when parameter is set but empty:

x            ${x+alt}   ${x:+alt}
------------ ---------- ----------
unset                ''         ''
set to ''           alt         ''
non-empty           alt        alt
  • I'm curious why this was downvoted; is this answer incorrect? – dhag Dec 22 '15 at 21:53
  • yeah! what's obsolete? will you fix that please? also - i think i understand what you mean, and this part wasn't worth a downvote, probably - but can you clear up which is which when you refer to first? – mikeserv Dec 22 '15 at 21:58
  • I said "appears to be" obsolete because the versions without : are undocumented in my version of bash, so it's a fair guess that this version of bash consider that feature obsolete. I'd love to be corrected. Regarding the second point (see what I did there), while I agree that the wording in your answer is more explicit, I think mine is completely unambiguous. I'll edit to improve clarity. – dhag Dec 22 '15 at 22:18
  • id like to upvote it but the obsolete thing gets me. anyway, man bash says this (and then lists each form explicitly) under the heading EXPANSION and the subheading PARAMETERS: When not performing substring expansion, using the forms documented below (e.g., :-), bash tests for a parameter that is unset or null. Omitting the colon results in a test only for a parameter that is unset. - yours doesn't have that? Anyway, it's hardly authoritative. – mikeserv Dec 22 '15 at 22:23
  • @mikeserv: My copy of the GNU bash documentation does have the wording that you quote, which I had missed on a first read. I guess that makes it explicit that the feature is officially supported in that implementation. – dhag Dec 23 '15 at 13:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.