In the Bash Reference Manual, chapter 4.1, in the part about the test command:
Expressions may be combined using the following operators, listed in decreasing order of precedence. The evaluation depends on the number of arguments; see below. Operator precedence is used when there are five or more arguments.
! expr True if expr is false.
( expr ) Returns the value of expr. This may be used to override the normal precedence of operators.
...
Seems from this that one can do something like:
if [ 3 == 2 -a (2 == 2 -o 2 == 2) ];
The paranthesis () in this case will override the normal precedence (which is the -a first, in which case the whole expression will be true), but when I try to run this I get:
/test.sh: line 3: syntax error near unexpected token `('
./test.sh: line 3: `if [ 3 == 2 -a (2 == 2 -o 2 == 2) ];'
CodePudding user response:
Use of -a
, -o
, and parenthesis is marked as obsolescent in the POSIX standard for test
. If you really want to use them, though, you need to quote or escape the parens so they're passed to [
(aka test
) as arguments, rather than interpreted by the shell as syntax:
if [ 3 = 2 -a '(' 2 = 2 -o 2 = 2 ')' ]; then # OBSOLETE SYNTAX, DO NOT USE
Note that if you put this code into http://shellcheck.net/, it will correctly throw warning SC2166. Reading the wiki page describing that warning (linked above) is strongly recommended.
Avoiding obsolescent syntax, your line is correctly written as:
if [ 3 = 2 ] && { [ 2 = 2 ] || [ 2 = 2 ]; }; then
Note that string comparison is =
, not ==
. There is no POSIX-standard ==
operator for test
.
If you want bash-only extensions, use [[
instead of [
; that does let you reliably use parenthesis (and also makes ==
reliably available, though using =
is better habit even then to develop finger memory compatible with POSIX-baseline shells):
if [[ 3 = 2 && ( 2 = 2 || 2 = 2 ) ]]; then
CodePudding user response:
Actually this text means that "!" just switch true and false. It is not about parenthesis because test operator have no parenthesis in his syntax.
If you need several items to test, you should use just "-a"/"-o" options or separate test operators which you can combine in different groups you need:
if [ 3 == 2 ] && ( [ 2 == 2 -o 2 == 2 ] ); then