6

Bash manual says:

A parameter is set if it has been assigned a value. The null string is a valid value.

...

If value is not given, the variable is assigned the null string.

Is the null string the same as ""?

Are their lengths both zero? Can both be tested by conditional expressions -z or -n which tests if the length of a string is zero or nonzero?

6

Yes. Using the test from this answer:

$ [ -n "${a+1}" ] && echo "defined" || echo "not defined"
not defined
$ a=""
$ [ -n "${a+1}" ] && echo "defined" || echo "not defined"
defined
$ b=
$ [ -n "${b+1}" ] && echo "defined" || echo "not defined"
defined

So setting the variable to "" is the same as setting it to empty value. Therefore, empty value and "" are the same.

8

Yes, a null string in that context is a string of length 0 containing no byte at all. In bash:

var=
var=''
var=""
var=$''
var=$""
var=$(true) # or any command that outputs nothing or only newline
            # characters
var=`true`
var=${null_or_unset_var}
var=''""$''$""$(true)"`true`"

But also in bash, as a side effect of bash (contrary to zsh) not supporting NUL bytes in its variables (as it uses NUL-delimited C strings internally):

var=$'\0'
var=$'\u0000'
var=$'\c@'
var=$'\x00'
var=$'\0\0\0\0\0'

In all those cases, $var will be set but contain nothing (the null string). echo "${#var}" will output 0, [ -z "$var" ] will return true and printf %s "$var" will output nothing.

After unset var (but beware of the bug/misfeature of bash, mksh and yash where unset may reveal a version of $var from an outer scope instead of unsetting it if you're doing that from a function called from another function that had declared the variable local), $var has no value, null or not.

However $var still expands to nothing (to the null string) unless the nounset option is on. There are other differences between unset variables and variables assigned an empty value:

  • ${var?} triggers an error when $var is unset
  • ${var+x} expands to x if $var has any value (even null)
  • ${var-x} expands to x if $var is unset
  • [[ -v var ]] returns false if $var is unset
  • if the variable is marked for export, then var= is passed in the environment of every command if it's set, or not passed at all otherwise.

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.