On 22/12/15 00:21, 積丹尼 Dan Jacobson wrote: >>>>>> "EB" == Eric Blake <[email protected]> writes: > > EB> On 12/21/2015 05:00 PM, 積丹尼 Dan Jacobson wrote: >>> OK. Also make sure (info "(coreutils) test invocation") makes it clear that >>> one cannot use >>> test -f $1 -a $1 ! -ot $2 #and must use >>> test -f $1 -a ! $1 -ot $2 #. > > EB> Use of -a in test is inherently non-portable. POSIX even says so - > EB> there are some expressions which are completely ambiguous when you > EB> attempt to use -a or -o. > > Mmmm! The documentation should mention that! > > EB> Also, your lack of quoting is a classic pitfall for how to incorrectly > EB> use test. > > EB> Better than what you typed would be using: > > EB> test -f "$1" && test ! "$1" -ot "$2" > > Mmmm, quote tips only mention in the case of (info "(coreutils) String > tests"). > Maybe need to mention in more places!
Patch V2 attached. thanks, Pádraig
>From 0c4ea11827d244c4938be9d08398107b57c86b53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= <[email protected]> Date: Mon, 21 Dec 2015 17:57:30 +0000 Subject: [PATCH] doc: describe test operator precedence and associativity * doc/coreutils.texi (Connectives for test): Add notes on precedence and associativity. Also mention the portability caveats with these operators. Fixes http://bugs.gnu.org/22216 --- doc/coreutils.texi | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/doc/coreutils.texi b/doc/coreutils.texi index 33be4d8..0db3225 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -12638,25 +12638,54 @@ test 0x100 -eq 1 @cindex logical connectives @cindex connectives, logical -The usual logical connectives. +Note it's preferred to use shell logical primitives +rather than these logical connectives internal to @command{test}, +because an expression may become ambiguous +depending on the expansion of its parameters. + +For example, this becomes ambiguous when @samp{$1} +is set to @samp{'!'} and @samp{$2} to the empty string @samp{''}: + +@example +test "$1" -a "$2" +@end example + +and should be written as: + +@example +test "$1" && test "$2" +@end example + +Note the shell logical primitives also benefit from +short circuit operation, which can be significant +for file attribute tests. @table @samp @item ! @var{expr} @opindex ! True if @var{expr} is false. +@samp{!} has lower precedence than all parts of @var{expr}. +Note @samp{!} needs to be specified to the left +of a binary expression, I.E. @samp{'!' 1 -gt 2} +rather than @samp{1 '!' -gt 2}. +Also @samp{!} is a shell special character and needs to be quoted. + @item @var{expr1} -a @var{expr2} @opindex -a @cindex logical and operator @cindex and operator True if both @var{expr1} and @var{expr2} are true. +@samp{-a} is left associative, +and has a higher precedence than @samp{-o}. @item @var{expr1} -o @var{expr2} @opindex -o @cindex logical or operator @cindex or operator True if either @var{expr1} or @var{expr2} is true. +@samp{-o} is left associative. @end table -- 2.5.0
