Bug with 'test' built-in.

2006-08-10 Thread John Wenker
From: [EMAIL PROTECTED]
To: bug-bash@gnu.org
Subject: Bug with 'test' built-in.

Configuration Information [Automatically generated, do not change]:
Machine: i686
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='i686' 
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i686-pc-linux-gnu' 
-DCONF_VENDOR='pc' -DSHELL -DHAVE_CONFIG_H  -D_GNU_SOURCE  -I.  -I. 
-I./include -I./lib -O2 -march=i386 -mcpu=i686
uname output: Linux ragtop 2.4.18-3 #1 Thu Apr 18 07:32:41 EDT 2002 i686 
unknown
Machine Type: i686-pc-linux-gnu

Bash Version: 2.05a
Patch Level: 0
Release Status: release

Description:
There is a problem using '!' (boolean negation) with the -a flag
  of the 'test' built-in command.  The following construct
  _always_ evaluates true, regardless of whether the file exists
  or not.

 if [ ! -a file ]; then
echo "This line always prints no matter what."
 else
echo "This line never prints."
 fi

  Using -a w/o the negation works fine.

Repeat-By:
[Describe the sequence of events that causes the problem
to occur.]

Fix:
[Description of how to fix the problem.  If you don't know a
fix for the problem, don't include this section.]


___
Bug-bash mailing list
Bug-bash@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-bash


Re: Bug with 'test' built-in.

2006-08-10 Thread Paul Jarc
John Wenker <[EMAIL PROTECTED]> wrote:
>   The following construct _always_ evaluates true, regardless of
>   whether the file exists or not.
>
>  if [ ! -a file ]; then
> echo "This line always prints no matter what."
>  else
> echo "This line never prints."
>  fi

-a can act as a prefix unary operator, or an infix binary "and"
operator.  When it appears as the second of three arguments (not
counting "]") in a test, it's treated as a binary operator, even if
the first argument is "!".  So in this case, "!" is test, and as a
single string it's only tested for non-emptiness, and so is considered
true.  Likewise for "file".  Since both subtests are true, the
combined "and" test is also true.

There are a few different ways to get the behavior you want.  You
could use "[ ! \( -a file \) ]" or "! [ -a file ]", although those are
not portable to some other shells.  (The behavior of a test is
generally more predictable when there are fewer arguments, so I'd go
with the second of those two, since it pulls the "!" outside the test
and leaves only two arguments for the test to examine.)  You could
also remove "!" and switch your "then" and "else" clauses, which works
with any shell.


paul


___
Bug-bash mailing list
Bug-bash@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-bash


Re: Bug with 'test' built-in.

2006-08-10 Thread mwoehlke

John Wenker wrote:

Configuration Information [Automatically generated, do not change]:
Machine: i686
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='i686' 
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i686-pc-linux-gnu' 
-DCONF_VENDOR='pc' -DSHELL -DHAVE_CONFIG_H  -D_GNU_SOURCE  -I.  -I. 
-I./include -I./lib -O2 -march=i386 -mcpu=i686
uname output: Linux ragtop 2.4.18-3 #1 Thu Apr 18 07:32:41 EDT 2002 i686 
unknown

Machine Type: i686-pc-linux-gnu

Bash Version: 2.05a


And despite this version being ancient, I'll point out that I can 
reproduce (assuming this isn't a case of wrong syntax) on 
"3.00.15(1)-release" (whatever that is; came with FC4) and 3.1.17 built 
from sources.


To venture a guess, it seems like '-a' is being parsed as 'and' in this 
case, rather than the test for file existence.



Patch Level: 0
Release Status: release

Description:
There is a problem using '!' (boolean negation) with the -a flag
  of the 'test' built-in command.  The following construct
  _always_ evaluates true, regardless of whether the file exists
  or not.

 if [ ! -a file ]; then
echo "This line always prints no matter what."
 else
echo "This line never prints."
 fi

  Using -a w/o the negation works fine.


--
Matthew
vIMprove your life! Now on version 7!



___
Bug-bash mailing list
Bug-bash@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-bash


Re: Bug with 'test' built-in.

2006-08-10 Thread Chet Ramey
Paul Jarc wrote:


> There are a few different ways to get the behavior you want.  

Paul is correct, though I'd simply use the standard `-e' operator to test
for file existence.  Unary -a exists only for compatibility.

Chet

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
   Live Strong.  No day but today.
Chet Ramey, ITS, CWRU[EMAIL PROTECTED]http://cnswww.cns.cwru.edu/~chet/


___
Bug-bash mailing list
Bug-bash@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-bash


Re: Bug with 'test' built-in.

2006-08-10 Thread mwoehlke

Paul Jarc wrote:

John Wenker <[EMAIL PROTECTED]> wrote:

  The following construct _always_ evaluates true, regardless of
  whether the file exists or not.

 if [ ! -a file ]; then
echo "This line always prints no matter what."
 else
echo "This line never prints."
 fi


-a can act as a prefix unary operator, or an infix binary "and"
operator.  When it appears as the second of three arguments (not
counting "]") in a test, it's treated as a binary operator, even if
the first argument is "!".  So in this case, "!" is test, and as a
single string it's only tested for non-emptiness, and so is considered
true.  Likewise for "file".  Since both subtests are true, the
combined "and" test is also true.

There are a few different ways to get the behavior you want.  You
could use "[ ! \( -a file \) ]" or "! [ -a file ]", although those are
not portable to some other shells.  (The behavior of a test is
generally more predictable when there are fewer arguments, so I'd go
with the second of those two, since it pulls the "!" outside the test
and leaves only two arguments for the test to examine.)  You could
also remove "!" and switch your "then" and "else" clauses, which works
with any shell.


I *know* '! [ -a file ]' is not portable. I tried to use it in some 
script, somewhere, at some time, and it was sometimes treated as history 
expansion. Switching clauses may be the only safe way.


--
Matthew
vIMprove your life! Now on version 7!



___
Bug-bash mailing list
Bug-bash@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-bash


Re: Bug with 'test' built-in.

2006-08-10 Thread Paul Jarc
mwoehlke <[EMAIL PROTECTED]> wrote:
> I *know* '! [ -a file ]' is not portable. I tried to use it in some 
> script, somewhere, at some time, and it was sometimes treated as history 
> expansion.

Quoting the "!" would take care of that particular problem, but there
are some older shells, like Solaris /bin/sh, where the "!" command
doesn't exist at all, so if this script will have to run in anything
but bash, it'd still be good to use one of the other methods.


paul


___
Bug-bash mailing list
Bug-bash@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-bash


Re: Bug with 'test' built-in.

2006-08-10 Thread mwoehlke

Paul Jarc wrote:

mwoehlke <[EMAIL PROTECTED]> wrote:
I *know* '! [ -a file ]' is not portable. I tried to use it in some 
script, somewhere, at some time, and it was sometimes treated as history 
expansion.


Quoting the "!" would take care of that particular problem, but there
are some older shells, like Solaris /bin/sh, where the "!" command
doesn't exist at all, so if this script will have to run in anything
but bash, it'd still be good to use one of the other methods.


Hehe, yeah, I have to maintain scripts that run under "/bin/sh" on... 
oh, about nine different platforms. :-) That's always a frustrating 
exercise in portability, and not just w.r.t. the shell. For instance, 
there is one script that breaks with certain non-GNU versions of 'awk' 
and 'tail', and there have been plenty of times I've put in conditional 
code. Heck, I've even done conditional code based on the version of 
bash! :-)


--
Matthew
vIMprove your life! Now on version 7!



___
Bug-bash mailing list
Bug-bash@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-bash