bash compare empty strings bug

$ [ $(echo) = $(echo) ]
$ echo $?
0
$ [ $(echo) != $(echo) ]
$ echo $?
0

Is this a bug?

P.S. I noticed this while trying to test if a string was empty; it appears I can use test -z for that purpose, but still am curious about this.

Answers 2

  • It's not a bug.

    You did not quote the command substitution, so it was expanded into nothing (instead of remaining an empty string). The tests ran are actually:

    [ = ]
    [ != ]
    

    With a single argument, [ ] tests whether the argument is not an empty string, and indeed neither = nor != are empty strings.

    Use quoting

    (unless you need the effects of unquoted expansion, which you likely won't)

    [ "$(echo)" = "" ] # $? = 0
    [ "$(echo)" != "" ] # $? = 1
    

  • When you do [ $(echo) != $(echo) ] without quoting, it's equivalent to [ != ]

    Now, man bash says under SHELL BUILTIN COMMANDS that the behavior of the [ ... ] test depends on the number of arguments as follows:

              0 arguments
                     The expression is false.
              1 argument
                     The expression is true if and only if the argument is not null.
    

    So since the string != is not null, the test is TRUE.

    If you quote the arguments, you will get the expected behaviour:

    $ [ "$(echo)" != "$(echo)" ]
    $ echo $?
    1
    $ [ "$(echo)" = "$(echo)" ]
    $ echo $?
    0
    

    because you are now giving it 3 arguments:

      3 arguments
             The following conditions are applied in the order listed.
             If the second argument is one of the  binary  conditional
             operators listed above under CONDITIONAL EXPRESSIONS, the
             result of the expression is the result of the binary test
             using  the first and third arguments as operands.  The -a
             and -o operators are  considered  binary  operators  when
             there  are  three arguments.  If the first argument is !,
             the value is the negation of the two-argument test  using
             the second and third arguments.  If the first argument is
             exactly ( and the third argument is exactly ), the result
             is  the one-argument test of the second argument.  Other?
             wise, the expression is false.
    

Related Questions