Bug with 'test' built-in.
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.
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.
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.
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.
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.
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.
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