>From 0c4ea11827d244c4938be9d08398107b57c86b53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= 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{''}: + address@hidden +test "$1" -a "$2" address@hidden example + +and should be written as: + address@hidden +test "$1" && test "$2" address@hidden 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. address@hidden 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. address@hidden 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. address@hidden is left associative. @end table -- 2.5.0