Are the null string and "" the same string?

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.

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.

Tags:

Bash