[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Inconsistent string comparison operators n and z
From: |
Greg Wooledge |
Subject: |
Re: Inconsistent string comparison operators n and z |
Date: |
Mon, 9 Jun 2014 11:54:50 -0400 |
User-agent: |
Mutt/1.4.2.3i |
On Mon, Jun 09, 2014 at 01:11:31PM +0000, Thibault, Daniel wrote:
> Consider these lines:
>
> $ if [ -z `pgrep pname` ]; then echo "not r" ; else echo "r" ; fi
> $ if [ ! -z `pgrep pname` ]; then echo "r" ; else echo "not r" ; fi
> $ if [ -n `pgrep pname` ]; then echo "r" ; else echo "not r" ; fi
> $ if [ ! -n `pgrep pname` ]; then echo "not r" ; else echo "r" ; fi
No, these are wrong. You must double-quote the command substitutions.
> Turns out this is how the script needs to be written to work correctly:
>
> $ if [ -z "`pgrep pname`" ]; then echo "not r" ; else echo "r" ; fi
> $ if [ ! -z "`pgrep pname`" ]; then echo "r" ; else echo "not r" ; fi
> $ if [ -n "`pgrep pname`" ]; then echo "r" ; else echo "not r" ; fi
> $ if [ ! -n "`pgrep pname`" ]; then echo "not r" ; else echo "r" ; fi
Oh, you already knew that? Then why are you filing a bug report?
When you use [ or test (but not when you use the [[ keyword), all arguments
undergo standard word-splitting and globbing. When you have a command
that can return 0, 1, 2 or more words (like pgrep) it is vitally important
that you quote it so that bash does not expand it into an indeterminate
number of words.
Your first command, [ -z `pgrep pname` ], could expand like this:
[ -z 123 456 789 ]
This will rightfully give you an error like "bash: [: too many arguments".
All the other unquoted cases are similar. They are all wrong -- they may
work SOME of the time, or even MOST of the time, but they will not work
ALL of the time.
The quoted versions are correct, because they force bash to suppress
word splitting. The output of pgrep will always be passed as a single
argument to the [ command. This is what you want.