help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Help-bash] bash lazy evaluation with -a


From: Eric Blake
Subject: Re: [Help-bash] bash lazy evaluation with -a
Date: Tue, 24 Jun 2014 12:47:00 -0600
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0

On 06/24/2014 10:45 AM, Ken Goldman wrote:
> (checking before I report a bug)
> 
> I inherited some code that looks like this:
> 
>     if [ $# -gt 3 -a $3 = "-ks" ];then
>           EC_SIGNING_KEY_SIZE=$4
>     fi
> 
> When I run with 2 arguments, I get:
> 
>     rpm.sh: line 514: [: too many arguments
> 
> I think the coder expected the left side of the -a to be false, and thus
> the right side would not be evaluated.  Certainly C code does that.  I
> suspect that my invocation with $3 empty causes the error.
> 
> Is this implementation dependent and thus a bug, or is my analysis wrong?

This is a bug in your code, not in bash.  POSIX says that -a is NOT
portable (likewise for -o), and should be avoided.  At a bare minimum,
what should this produce?

[ "$a" -a "$b" ]

Is it the binary test of $a is not empty, and $b is not empty?  Or, if
$a happens to contain !, could it be the negation of the unary test of
whether $b names a file?

Bash can only short-circuit operations if it can parse the syntax of
what operations to perform.  In your case, because you forgot to quote
$3, bash only sees:

[ $# -gt 3 -a = -ks ]

which bash does not know how to parse.  Bash's behavior of rejecting
your syntax is appropriate, and is not a bug in bash, but evidence of
the bug in your command line.

If you use [[ ]] instead of [ ], then you are outside the (current)
bounds of POSIX, and can therefore rely on -a having consistent behavior
(although POSIX may be standardizing [[ ]] in the future, and bash may
have to make tweaks to comply with what gets standardized).
Furthermore, if you use [[ ]], then you don't have to worry about
quoting $3, and could use && instead of -a (less confusion).  So in
short, you want to use either of these forms:

[ $# -gt 3 ] && [ "$3" = -ks ]
[[ $# -gt 3 && $3 = -ks ]]

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]