Re: 'test' builtin of bash returns wrong value for '! -a FILE' operation
tags 426990 - moreinfo tags 426990 + upstream # documentation bug severity 426990 minor retitle 426990 bash: "help test" gives no hint of complicated precedence rules quit OZAKI Masanobu wrote: > On Fri, 2010-11-05 at 03:17:13 -0500, Jonathan Nieder > wrote: >>> Please try >>> % bash -c 'test ! -a . && echo true' >>> and compare with the result of >>> % bash -c '/usr/bin/test ! -a . && echo true' >> >> So which one is right? > > Both should echo "true", but the former did not: I found that the former > sometimes returns the correct result, but have not found what makes the > difference. Thanks. The second one doesn't echo "true", does it? Summarizing: There are two -a operators: a unary one and a binary one. This results in reduce/reduce conflicts when parsing a "test" expression. "help test" says: See the bash manual page bash(1) for the handling of parameters (i.e., missing parameters). which does not really tempt me to look at the manual. bash(1) says: Expressions may be combined using the following operators, listed in decreasing order of precedence. giving an order of precedence with ! before -a. Then it quickly corrects itself: test and [ evaluate conditional expressions using a set of rules based on the number of arguments. 0 arguments The expression is false. [...] 3 arguments If the second argument is one of the binary conditional operators listed above under CONDITIONAL EXPRESSIONS, the result of the expression is the result of the binary test using the first and third arguments as operands. The -a and -o operators are considered binary operators when there are three arguments. That answers the question. Unfortunately, the next sentence is inconsistent with that answer: If the first argument is !, the value is the negation of the two-argument test using the second and third arguments. Suggested changes: 1. Change the parenthesis in "help bash" to something like "(e.g., operator precedence and missing parameters)". 2. Change the second paragraph in the description in bash(1) of the test builtin to something like Expressions may be combined using the following operators. The evaluation depends on the number of arguments; see below. When 5 or more arguments are present, this list is in decreasing order of precedence. 3. Add the word "Otherwise," before "If the first argument is !" in the 3-argument case. Thoughts? I can try writing a patch if this looks like a good idea.
Commands executed with $($prog) do not run properly
Configuration Information [Automatically generated, do not change]: Machine: i486 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='i486' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i486-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 main.hgbhome.net 2.6.18-4-686 #1 SMP Wed May 9 23:03:12 UTC 2007 i686 GNU/Linux Machine Type: i486-pc-linux-gnu Bash Version: 3.2 Patch Level: 39 Release Status: release Description: Hi, if a program ist started with $($prog) the output is different from or even $(). Example with find (excluding a directory from search): $ ls -l /test total 16 drwxrwxr-x 2 hgb hgb 4096 Nov 6 02:14 a drwxrwxr-x 2 hgb hgb 4096 Nov 6 02:14 b drwxrwxr-x 2 hgb hgb 4096 Nov 6 02:14 c drwxrwxr-x 2 hgb hgb 4096 Nov 6 02:14 d $ find /test -type d ! -wholename "/test" /test/c /test/b /test/d /test/a $ echo "$(find /test -type d ! -wholename "/test")" /test/c /test/b /test/d /test/a $ prog='find /test -type d ! -wholename "/test"' $ echo $prog find /test -type d ! -wholename "/test" $ echo "$($prog)" /test /test/c /test/b /test/d /test/a $ As seen above /test ist shown when $prog is executed. I see the same behavior with GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu) (CentOS) GNU bash, version 3.2.39(1)-release (i486-pc-linux-gnu) (debian) I understand that the above looks crazy and not like a problem out of real life I had to use find to crawl through a huge tree and remove only a few files in it. I came across the above problem when feeding an array with the output of find; I fixed it for now by removing the unwanted entries from the output array. Thanks in advance for looking into this. Regards -- hgb
Commands executed with $($prog) do not run properly
From: Hans-Georg Bork To: bug-bash@gnu.org, b...@packages.debian.org Subject: Commands ran with $($prog) do not run properly 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 linprofs-hgb 2.6.32-5-amd64 #1 SMP Wed Oct 20 00:05:22 UTC 2010 x86_64 GNU/Linux Machine Type: x86_64-pc-linux-gnu Bash Version: 4.1 Patch Level: 5 Release Status: release Description: Hi, if a program ist started with $($prog) the output is different from or even $(). Example with find (excluding a directory from search): $ ls -l /test total 16 drwxrwxr-x 2 hgb hgb 4096 Nov 6 02:14 a drwxrwxr-x 2 hgb hgb 4096 Nov 6 02:14 b drwxrwxr-x 2 hgb hgb 4096 Nov 6 02:14 c drwxrwxr-x 2 hgb hgb 4096 Nov 6 02:14 d $ find /test -type d ! -wholename "/test" /test/c /test/b /test/d /test/a $ echo "$(find /test -type d ! -wholename "/test")" /test/c /test/b /test/d /test/a $ prog='find /test -type d ! -wholename "/test"' $ echo $prog find /test -type d ! -wholename "/test" $ echo "$($prog)" /test /test/c /test/b /test/d /test/a $ As seen above /test ist shown when $prog is executed. I see the same behavior with GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu) (CentOS) GNU bash, version 3.2.39(1)-release (i486-pc-linux-gnu) (debian) I understand that the above looks crazy and not like a problem out of real life ... I had to use find to crawl through a huge tree and remove only a few files in it. I came across the above problem when feeding an array with the output of find; I fixed it for now by removing the unwanted entries from the output array. Thanks in advance for looking into this. Regards -- hgb
Re: Commands executed with $($prog) do not run properly
On Sat, Nov 6, 2010 at 6:12 AM, wrote: > Configuration Information [Automatically generated, do not change]: > Machine: i486 > OS: linux-gnu > Compiler: gcc > Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='i486' > -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i486-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 main.hgbhome.net 2.6.18-4-686 #1 SMP Wed May 9 23:03:12 > UTC 2007 i686 GNU/Linux > Machine Type: i486-pc-linux-gnu > > Bash Version: 3.2 > Patch Level: 39 > Release Status: release > > Description: > > Hi, > > if a program ist started with $($prog) the output is different from > or even $(). Example with find (excluding a directory from search): > > $ ls -l /test > total 16 > drwxrwxr-x 2 hgb hgb 4096 Nov 6 02:14 a > drwxrwxr-x 2 hgb hgb 4096 Nov 6 02:14 b > drwxrwxr-x 2 hgb hgb 4096 Nov 6 02:14 c > drwxrwxr-x 2 hgb hgb 4096 Nov 6 02:14 d > $ find /test -type d ! -wholename "/test" > /test/c > /test/b > /test/d > /test/a > $ echo "$(find /test -type d ! -wholename "/test")" > /test/c > /test/b > /test/d > /test/a > $ prog='find /test -type d ! -wholename "/test"' > $ echo $prog > find /test -type d ! -wholename "/test" > $ echo "$($prog)" > /test > /test/c > /test/b > /test/d > /test/a > $ > > As seen above /test ist shown when $prog is executed. > > I see the same behavior with > GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu) (CentOS) > GNU bash, version 3.2.39(1)-release (i486-pc-linux-gnu) (debian) > > > I understand that the above looks crazy and not like a problem out of real > life > I had to use find to crawl through a huge tree and remove only a few > files > in it. I came across the above problem when feeding an array with the output > of > find; I fixed it for now by removing the unwanted entries from the output > array. > > Thanks in advance for looking into this. > > Regards > -- hgb > > > > your problem is there: $ prog='find /test -type d ! -wholename "/test"' The quotes around " " are quoted, they are not special to the shell anymore, only the literal, non quoted quotes are special to the shell. When you later execute $prog, the " " are not removed, they are no more special than the other literal chars. check this http://mywiki.wooledge.org/BashFAQ/050