Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have seen the following technique used many times on many different shells, to test if a variable is empty:

if [ "x$1" = "x" ]; then 
    # Variable is empty

Are there any advantages on using this over the more canonical if [ -z "$1" ]? Could it be a portability issue?

share|improve this question
up vote 10 down vote accepted

Some historical shells implemented a very simple parser that could get confused by things like [ -n = "" ] where the first operand to = looks like an operator, and would parse this as [ -n = ] or cause a syntax error. In [ "x$1" = x"" ], the x prefix ensures that x"$1" cannot possibly look like an operator, and so the only way the shell can parse this test is by treating = as a binary operator.

All modern shells, and even most older shells still in operation, follow the POSIX rules which mandate that all test expressions of up to 4 words be parsed correctly. So [ -z "$1" ] is a proper way of testing if $1 is empty, and [ "$x" = "$y" ] is a proper way to test the equality of two variables.

Even some current shells can get confused with longer expressions, and a few expressions are actually ambiguous, so avoid using the -a and -o operators to construct longer boolean tests, and instead use separate calls to [ and the shell's own && and || boolean operators.

share|improve this answer
It's not only historical shells. Some ksh88 based shs on some commercial Unices still have the issue. See here for details. – Stéphane Chazelas Nov 27 '12 at 21:00
This statement is incorrect: [ -z "$1" ] is a proper way of testing if $1 is empty. sh -c '[ -z "$1" ]' ''; sh -c '[ -z "$1" ]' - both return 0, but in the second case $1 cannot be empty because it does not exist. – mikeserv Jul 29 '14 at 15:58

According to http://www.mpi-inf.mpg.de/~uwe/lehre/unixffb/quoting-guide.html, the -z test is unsafe in some implementations, presumably when "interesting" strings like "-o a=a" are tested.

share|improve this answer

The above tests will also cause an error if you run with "set -u" or "set -o nounset"

A more stable way to check for an empty variable would be to use parameter expansion:

MYVAR={$MYVAR:-"Bad Value"}

This method works for the traditional bourne shell, as well as ksh, and bash.

share|improve this answer
    function isBlank {
 valueNoSpaces=$(echo "$@" | tr -d ' ')

 if [  "$valueNoSpaces" == null ] || [ -z "$valueNoSpaces" ] 
       echo true ;
       echo ""  ;

if [ $(isBlank "      ") ] 
    echo "isBlank \"      \" : it's blank"
    echo " isBlank \"      \": it is not blank"

if [ $(isBlank "abc") ] 

    echo "isBlank \"abc\" : it's blank"
    echo "isBlank \"abc\" :it is not blank"

if [ $(isBlank null) ] 
      echo "isBlank null : it's blank"
    echo "isBlank null : it is not blank"

if [ $(isBlank "") ] 
    echo "isBlank \"\" : it's blank"
    echo "isBlank \"\" : it is not blank"

isBlank "      " : it's blank

isBlank "abc" :it is not blank

isBlank null : it's blank

isBlank "" : it's blank
share|improve this answer
Hi! I'm not sure how this answers the question, which asks why to use = versus -z, now how. – dhag Aug 28 '15 at 20:19

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.