Advanced BashScripting Guide: An indepth exploration of the art of shell scripting  

Prev  Chapter 33. Miscellany  Next 
In a script, operations execute in order of precedence: the higher precedence operations execute before the lower precedence ones. [1]
Table 331. Operator Precedence
Operator  Meaning  Comments 

HIGHEST PRECEDENCE  
var++ var  postincrement, postdecrement  Cstyle operators 
++var var  preincrement, predecrement  
! ~  negation  logical / bitwise, inverts sense of following operator 
**  exponentiation  arithmetic operation 
* / %  multiplication, division, modulo  arithmetic operation 
+   addition, subtraction  arithmetic operation 
<< >>  left, right shift  bitwise 
z n  unary comparison  string is/isnot null 
e f t x, etc.  unary comparison  filetest 
< lt > gt <= le >= ge  compound comparison  string and integer 
nt ot ef  compound comparison  filetest 
== eq != ne  equality / inequality  test operators, string and integer 
&  AND  bitwise 
^  XOR  exclusive OR, bitwise 
  OR  bitwise 
&& a  AND  logical, compound comparison 
 o  OR  logical, compound comparison 
?:  trinary operator  Cstyle 
=  assignment  (do not confuse with equality test) 
*= /= %= += = <<= >>= &=  combination assignment  timesequal, divideequal, modequal, etc. 
,  comma  links a sequence of operations 
LOWEST PRECEDENCE 
In practice, all you really need to remember is the following:
The "My Dear Aunt Sally" mantra (multiply, divide, add, subtract) for the familiar arithmetic operations.
The compound logical operators, &&, , a, and o have low precedence.
The order of evaluation of equalprecedence operators is usually lefttoright.
Now, let's utilize our knowledge of operator precedence to analyze a couple of lines from the /etc/init.d/functions file, as found in the Fedora Core Linux distro.
1 while [ n "$remaining" a "$retry" gt 0 ]; do 2 3 # This looks rather daunting at first glance. 4 5 6 # Separate the conditions: 7 while [ n "$remaining" a "$retry" gt 0 ]; do 8 # condition 1 ^^ condition 2 9 10 # If variable "$remaining" is not zero length 11 #+ AND (a) 12 #+ variable "$retry" is greaterthan zero 13 #+ then 14 #+ the [ expresionwithinconditionbrackets ] returns success (0) 15 #+ and the whileloop executes an iteration. 16 # ============================================================== 17 # Evaluate "condition 1" and "condition 2" ***before*** 18 #+ ANDing them. Why? Because the AND (a) has a lower precedence 19 #+ than the n and gt operators, 20 #+ and therefore gets evaluated *last*. 21 22 ################################################################# 23 24 if [ f /etc/sysconfig/i18n a z "${NOLOCALE:}" ] ; then 25 26 27 # Again, separate the conditions: 28 if [ f /etc/sysconfig/i18n a z "${NOLOCALE:}" ] ; then 29 # condition 1 ^^ condition 2 30 31 # If file "/etc/sysconfig/i18n" exists 32 #+ AND (a) 33 #+ variable $NOLOCALE is zero length 34 #+ then 35 #+ the [ testexpresionwithinconditionbrackets ] returns success (0) 36 #+ and the commands following execute. 37 # 38 # As before, the AND (a) gets evaluated *last* 39 #+ because it has the lowest precedence of the operators within 40 #+ the test brackets. 41 # ============================================================== 42 # Note: 43 # ${NOLOCALE:} is a parameter expansion that seems redundant. 44 # But, if $NOLOCALE has not been declared, it gets set to *null*, 45 #+ in effect declaring it. 46 # This makes a difference in some contexts. 
To avoid confusion or error in a complex sequence of test operators, break up the sequence into bracketed sections.

[1]  Precedence, in this context, has approximately the same meaning as priority 