Is there any practical difference between unsetting an environment variable and setting it to the empty string?
3 Answers
Each application is free to interpret an unset variable and an empty variable in the same way or not. It is generally a bad idea to give them different meanings, and most applications don't do it, but it happens.
An example in shells themselves is the IFS
shell variable (which is usually not exported in the environment, but the same principle applies). If unset, the shell behaves as if the value was $' \t\n'
.
In a shell script, $foo
expands to an empty string whether foo
is set to an empty value or unset. You can run the shell under the nounset
setting (set -u
or set -o nounset
), in which case the shell reports an error and exits if you try to expand an unset variable. Otherwise, you can distinguish between unset and empty variables with parameter expansion modifiers: ${foo:+a}
expands to a
if foo
is unset or empty and to the empty string otherwise, whereas ${foo+a}
expands to a
even if foo
is set to the empty string.

- 51,212

- 829,060
There is a difference, yes. But it is very subtle since evaluating an empty string and an unset variable are the same.
$ env - FOO= sh -c 'echo "X${FOO}X X${FOO:+x}X X${FOO+x}X"; env'
XX XX XxX
FOO=
PWD=/tmp
$ env - FOO= sh -c 'unset FOO; echo "X${FOO}X X${FOO:+x}X X${FOO+x}X"; env'
XX XX XX
PWD=/tmp
Both will have ${FOO:+x}
evaluate to an empty string. But ${FOO+x}
will evaluate to a "x" when FOO is an empty string.
One thing that I commonly use this for is to set up a $DEBUG
environment variable, and then use ${DEBUG+true}
in the program. Then I can set DEBUG to anything, including an empty string.
In higher level languages, like Perl and Python, this is the difference between "" and undef (Perl) or None (Python).

- 22,536
-
That's specific to Bourne-derived shells, and the behavior can be changed (at least in bash) with
set -o nounset.
cshand
tcshtreat unset and empty variables quite differently. There's a very real difference in what's stored, and in what the C function
getenv()` will return. – Keith Thompson Dec 26 '11 at 22:47
Bash script has an ability to distinguish between:
- unset (environment) variable
- variable set to null
- variable set to empty string
Due to many possibilities how to handle "default fallback", there is often no difference between these three cases. Coder tends just to use first one method found. One can handle default fallback like this:
FOO=${VARIABLE:-default} # If variable not set or null, use default.
FOO=${VARIABLE:+default} # If variable is set use, use default.
# all replacing commands an be used also without ':', so it handles null cases differently
FOO=${VARIABLE-default} # If variable not set, use default.
# somewhat also used in wild using "test" (see man test"
[[ -z "$FOO" ]] && FOO="defoltíček : "
I would prefer to keep possibility of empty string use in variable and thus I would use mostly this approach:
DEFAULT_INTERFACE=$(ip addr show | awk '/inet.*brd/{print $NF; exit}')
INTERFACE_TO_USE=${IFACE=$DEFAULT_INTERFACE}
NOTE: Using IFACE=
command will unset environment variable. Using IFACE=""
will set variable to empty string.
See also similar topic https://stackoverflow.com/questions/2013547/assigning-default-values-to-shell-variables-with-a-single-command-in-bash and also Set variable to expand to explicit empty string?

- 115
- 5
${foo+a}
documented? @Gilles – Jingguo Yao Jun 03 '19 at 11:48