6
# touch $$
# gzip $$
# gzip --test $$.gz
# echo $?
0
# OUT=$(gzip --test $$.gz)
# echo $OUT

# if [ -z $OUT ] ; then echo $$ ; fi
26521
# if [ -n $OUT ] ; then echo $$ ; fi
26521
# 

from bash(1)

   -z string
          True if the length of string is zero.
   string
   -n string
          True if the length of string is non-zero.

I'm confused, how is it zero and non-zero at the same time? How does one do check against if key has a value (using bash)?

0

2 Answers 2

15

[ .. ] follows the same rules as all other commands, namely Word Splitting applies. If OUT is empty (or unset), $OUT will expand to nothing, not even an empty argument.

So, [ -n $OUT ] expands to [, -n and ], and [ tests if -n is not an empty string. It is, so the test returns true.

You need to quote $OUT, as almost everywhere else:

if [ -n "$OUT" ]; then ...

See: When is double-quoting necessary? and Tests and Conditionals on BashGuide.

5

The command

[ -z $OUT ]

is exactly equivalent to

test -z $OUT

which, if $OUT is empty, is the same as

test -z

The behaviour of test depends on the number of parameters given on the command line. If given only a single parameter, as in test -n or test -z, the result will be "true" if the length of that parameter, when interpreted as a string, is non-zero.

This means that if $OUT is empty and unquoted, then test -z $OUT and test -n $OUT will both be true because -z and -n are both strings of non-zero length.

To remedy this, double-quote the variable expansion:

[ -n "$OUT" ]

See also

Not the answer you're looking for? Browse other questions tagged .