Skip to main content
"because" is duplicate to "the reason". Add comma mark for long clause.
Source Link

The reason, why [ x"${VAR}" = x ] is often recommended for testing whether a variable is either unset or set to the empty string, is because some implementations of the [ command (also known as test) are buggy. If VAR is set to something like -n, then some implementations will do the wrong thing when given [ "${VAR}" = "" ] because, since the first argument to [ is erroneously interpreted as the -n operator, not a string.

The reason why [ x"${VAR}" = x ] is often recommended for testing whether a variable is either unset or set to the empty string is because some implementations of the [ command (also known as test) are buggy. If VAR is set to something like -n, then some implementations will do the wrong thing when given [ "${VAR}" = "" ] because the first argument to [ is erroneously interpreted as the -n operator, not a string.

The reason, why [ x"${VAR}" = x ] is often recommended for testing whether a variable is either unset or set to the empty string, is some implementations of the [ command (also known as test) are buggy. If VAR is set to something like -n, then some implementations will do the wrong thing when given [ "${VAR}" = "" ], since the first argument to [ is erroneously interpreted as the -n operator, not a string.

add a table for easy reference
Source Link
Richard Hansen
  • 4k
  • 1
  • 20
  • 17

Here is the same thing but in handy table form:

                        +-------+-------+-----------+
                VAR is: | unset | empty | non-empty |
+-----------------------+-------+-------+-----------+
| [ -z "${VAR}" ]       | true  | true  | false     |
| [ -z "${VAR+set}" ]   | true  | false | false     |
| [ -z "${VAR-unset}" ] | false | true  | false     |
| [ -n "${VAR}" ]       | false | false | true      |
| [ -n "${VAR+set}" ]   | false | true  | true      |
| [ -n "${VAR-unset}" ] | true  | false | true      |
+-----------------------+-------+-------+-----------+

The ${VAR+foo} construct expands to the empty string if VAR is unset or to foo if VAR is set to anything (including the empty string).

The ${VAR+foo} construct expands to the empty string if VAR is unset or to foo if VAR is set to anything (including the empty string).

Here is the same thing but in handy table form:

                        +-------+-------+-----------+
                VAR is: | unset | empty | non-empty |
+-----------------------+-------+-------+-----------+
| [ -z "${VAR}" ]       | true  | true  | false     |
| [ -z "${VAR+set}" ]   | true  | false | false     |
| [ -z "${VAR-unset}" ] | false | true  | false     |
| [ -n "${VAR}" ]       | false | false | true      |
| [ -n "${VAR+set}" ]   | false | true  | true      |
| [ -n "${VAR-unset}" ] | true  | false | true      |
+-----------------------+-------+-------+-----------+

The ${VAR+foo} construct expands to the empty string if VAR is unset or to foo if VAR is set to anything (including the empty string).

added 513 characters in body
Source Link
Richard Hansen
  • 4k
  • 1
  • 20
  • 17

The following is an exampleA variable in bash (and any POSIX-compatible shell) can be in one of howthree states:

  • unset
  • set to the empty string
  • set to a non-empty string

Most of the time you canonly need to know if a variable is set to a non-empty string, but occasionally it's important to distinguish between unset fromand set to the empty string.

The following are examples of how you can test the various possibilities, and it works in bash or any POSIX-compatible shell:

if [ -z "${VAR}" ]; then
    echo "VAR is unset or set to the empty string"
fi
if [ -z "${VAR+set}" ]; then
    echo "VAR is unset"
fi
if [ -nz "${VAR+setVAR-unset}" ]; then
    echo "VAR is set, possibly to the empty string"
fi
if [ -zn "${VAR}" ]; then
    echo "VAR is set to a non-unsetempty string"
fi
if [ -n "${VAR+set}" ]; then
    echo "VAR is set, possibly to the empty string"
fi
if [ -n "${VAR-unset}" ]; then
    echo "VAR is either unset or set to a non-empty string"
fi

The ${VAR+foo} construct expands to the empty string if VAR is unset or to foo if VAR is set to anything (including the empty string).

The ${VAR-foo} construct expands to the value of VAR if set (including set to the empty string) and foo if unset. This is useful for providing user-overridable defaults (e.g., ${COLOR-red} says to use red unless the variable COLOR has been set to something).

The reason why [ x"${VAR}" = x ] is often recommended for testing whether a variable is either unset or set to the empty string is because some implementations of the [ command (also known as test) are buggy. If VAR is set to something like -n, then some implementations will do the wrong thing when given [ "${VAR}" = "" ] (becausebecause the first argument to [ is erroneously interpreted as anthe -n operator, not a string).

The following is an example of how you can distinguish unset from set to the empty string, and it works in any POSIX-compatible shell:

if [ -z "${VAR}" ]; then
    echo "VAR is unset or set to the empty string"
fi
if [ -z "${VAR+set}" ]; then
    echo "VAR is unset"
fi
if [ -n "${VAR+set}" ]; then
    echo "VAR is set, possibly to the empty string"
fi
if [ -z "${VAR-unset}" ]; then
    echo "VAR is set to the empty string"
fi
if [ -n "${VAR}" ]; then
    echo "VAR is set to a non-empty string"
fi

The ${VAR+foo} construct expands to the empty string if VAR is unset or to foo if VAR is set to anything (including the empty string).

The ${VAR-foo} construct expands to the value of VAR if set (including set to the empty string) and foo if unset. This is useful for providing user-overridable defaults (e.g., ${COLOR-red} says to use red unless the variable COLOR has been set to something).

The reason why [ x"${VAR}" = x ] is often recommended is because some implementations of the [ command (also known as test) are buggy. If VAR is set to something like -n, then some implementations will do the wrong thing when given [ "${VAR}" = "" ] (because the first argument to [ is erroneously interpreted as an operator, not a string).

A variable in bash (and any POSIX-compatible shell) can be in one of three states:

  • unset
  • set to the empty string
  • set to a non-empty string

Most of the time you only need to know if a variable is set to a non-empty string, but occasionally it's important to distinguish between unset and set to the empty string.

The following are examples of how you can test the various possibilities, and it works in bash or any POSIX-compatible shell:

if [ -z "${VAR}" ]; then
    echo "VAR is unset or set to the empty string"
fi
if [ -z "${VAR+set}" ]; then
    echo "VAR is unset"
fi
if [ -z "${VAR-unset}" ]; then
    echo "VAR is set to the empty string"
fi
if [ -n "${VAR}" ]; then
    echo "VAR is set to a non-empty string"
fi
if [ -n "${VAR+set}" ]; then
    echo "VAR is set, possibly to the empty string"
fi
if [ -n "${VAR-unset}" ]; then
    echo "VAR is either unset or set to a non-empty string"
fi

The ${VAR+foo} construct expands to the empty string if VAR is unset or to foo if VAR is set to anything (including the empty string).

The ${VAR-foo} construct expands to the value of VAR if set (including set to the empty string) and foo if unset. This is useful for providing user-overridable defaults (e.g., ${COLOR-red} says to use red unless the variable COLOR has been set to something).

The reason why [ x"${VAR}" = x ] is often recommended for testing whether a variable is either unset or set to the empty string is because some implementations of the [ command (also known as test) are buggy. If VAR is set to something like -n, then some implementations will do the wrong thing when given [ "${VAR}" = "" ] because the first argument to [ is erroneously interpreted as the -n operator, not a string.

added 2 characters in body
Source Link
Richard Hansen
  • 4k
  • 1
  • 20
  • 17
Loading
simplify the "VAR is set to the empty string" test
Source Link
Richard Hansen
  • 4k
  • 1
  • 20
  • 17
Loading
added 191 characters in body
Source Link
Richard Hansen
  • 4k
  • 1
  • 20
  • 17
Loading
Source Link
Richard Hansen
  • 4k
  • 1
  • 20
  • 17
Loading