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

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