Bash – In Bash, are if [ -z “$1” ] and if [ “$1” = “” ] the same

bashshell-script

In Bash shell scripting, what is the difference (if any) between the following two statements?

  1. if [ -z "$1" ]
  2. if [ "$1" = "" ]

I have found myself writing the second one in some scripts,
but then I read here that using -z achieves the same thing.

If there are problems using the second one, should we ignore that the first one looks a little better?

Best Answer

[ "$1" = "" ] and [ -z "$1" ] are exactly equivalent in bash and other POSIX-compliant shells. (Note that there must be a space on each side of the brackets, unless there is a non-word-constituent character like ;.)

[ is a shell built-in like any other; in fact it can also be spelled test (the only difference between the two is that [ requires a ] as the last argument). So if you run [ "$1" = "" ] with $1 expanding to -z, the test operator sees three arguments: -z, = and the empty string. Some older Bourne shells sometimes threw parse errors when an operand looked like an operator in this way, even if there was no ambiguity in the complete expression. I don't know if any version did in fact have trouble with this particular expression, but more complex expressions could throw them off. There may also have been versions that had trouble with empty words; these would not have supported [ -z "$1" ] either. A common shell idiom is [ x"$1" = x"" ]. It avoids any risk of having operands parsed as operators because no operator starts with a letter.

In ksh, bash and zsh, you can use the double bracket syntax, [[ -z $1 ]]. This newer syntax (it's from the late 1980s rather than the mid-1970s) eliminates the risk of having operands parsed as operators by using a special syntactic construct rather than an ordinary built-in. Operators must appear literally, unquoted within the double brackets, and you don't need to double quote variable expansions.