bug-bash
[Top][All Lists]
Advanced

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

builtin test command file existence fails with negation


From: Lynn Kerby
Subject: builtin test command file existence fails with negation
Date: Mon, 20 Jul 2009 22:41:56 -0700


Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' - DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-pc-linux-gnu' - DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' - DSHELL -DHAVE_CONFIG_H -I. -I../bash -I../bash/include -I../bash/ lib -g -O2 -Wall uname output: Linux virtsrv2 2.6.28-13-server #44-Ubuntu SMP Tue Jun 2 08:40:28 UTC 2009 x86_64 GNU/Linux
Machine Type: x86_64-pc-linux-gnu

Bash Version: 3.2
Patch Level: 48
Release Status: release

Description:
        Use of the '-a' option to the builtin test command fails to
        produce the correct result when used with negation. The specific
        error the case where the file exists and a "test ! -a file" is
        executed.  If the script is changed to use '-e' for file
        existence the result is correct as expected.  If the script is
        modified to place parenthesis around the '-a file' expression,
        the result is also correct.

Repeat-By:
        Run the following bash script to see all behaviors including the
        behavior of the /usr/bin/test command:

---------------cut------------
#!/bin/bash
#
fn=._you_better_not_have_this_file

trap "rm -f $fn" 0

for (( tc=0; tc < 4; tc++ ))
do
    echo "Starting case $tc"
    case $tc in
    "0")      # bash test builtin; bracket operator
        ts=\[
        te=\]
        to=-a
        ;;
    "1")      # bash test builtin; test
        ts=test
        te=
        to=-a
        ;;
    "2")      # system standalone test
        ts=/usr/bin/test
        te=
        to=-a
        ;;
    "3")      # bash test builtin; test; -e unary op
        ts=test
        te=
        to=-e
        ;;
    esac

    #
    if eval $ts $to $fn $te
    then
        echo "surprised (not good)"
    fi
    if eval $ts ! $to $fn $te
    then
        echo "file $fn not present (good)"
    fi
    touch $fn
    if eval $ts $to $fn $te
    then
        echo "file present (good)"
    fi
    if eval $ts ! $to $fn $te
    then
        echo "file $fn not present (bug)"
    fi

    echo "Completed case $tc"
    echo
    rm -f $fn
done
---------------cut------------

Fix:
        Changing the order of clauses in the three_arguments function to
        look for negation before the possibility of an and/or expression
        solved the problem for me.  It also passed the test cases for the
        test operator.  This is consistent with the way things are handled
        in the coreutils standalone test program.
        
--- bash-3.2-dist/test.c        2006-01-29 11:44:02.000000000 -0800
+++ bash-3.2/test.c     2009-07-20 19:20:08.000000000 -0700
@@ -709,14 +709,6 @@ three_arguments ()
       value = binary_operator ();
       pos = argc;
     }
-  else if (ANDOR (argv[pos+1]))
-    {
-      if (argv[pos+1][1] == 'a')
-       value = ONE_ARG_TEST(argv[pos]) && ONE_ARG_TEST(argv[pos+2]);
-      else
-       value = ONE_ARG_TEST(argv[pos]) || ONE_ARG_TEST(argv[pos+2]);
-      pos = argc;
-    }
   else if (argv[pos][0] == '!' && argv[pos][1] == '\0')
     {
       advance (1);
@@ -727,6 +719,14 @@ three_arguments ()
       value = ONE_ARG_TEST(argv[pos+1]);
       pos = argc;
     }
+  else if (ANDOR (argv[pos+1]))
+    {
+      if (argv[pos+1][1] == 'a')
+       value = ONE_ARG_TEST(argv[pos]) && ONE_ARG_TEST(argv[pos+2]);
+      else
+       value = ONE_ARG_TEST(argv[pos]) || ONE_ARG_TEST(argv[pos+2]);
+      pos = argc;
+    }
   else
test_syntax_error (_("%s: binary operator expected"), argv[pos +1]);

---EOF---






reply via email to

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