预计阅读本页时间:-
Integer Variables and Arithmetic
The expression $(($OPTIND - 1)) in the last graphics utility example shows another way that the shell can do integer arithmetic. As you might guess, the shell interprets words surrounded by $(( and )) as arithmetic expressions.[8]Variables in arithmetic expressions do not need to be preceded by dollar signs, though it is not wrong to do so.
Arithmetic expressions are evaluated inside double quotes, like tildes, variables, and command substitutions. We're finally in a position to state the definitive rule about quoting strings: when in doubt, enclose a string in single quotes, unless it contains tildes or any expression involving a dollar sign, in which case you should use double quotes.
广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元
For example, the date command on modern versions of UNIX accepts arguments that tell it how to format its output. The argument +%j tells it to print the day of the year, i.e., the number of days since December 31st of the previous year.
We can use +%j to print a little holiday anticipation message:
echo "Only $(( (365-$(date +%j)) / 7 )) weeks until the New Year"
We'll show where this fits in the overall scheme of command-line processing in Chapter 7.
The arithmetic expression feature is built into bash's syntax, and was available in the Bourne shell (most versions) only through the external command expr. Thus it is yet another example of a desirable feature provided by an external command being better integrated into the shell. getopts, as we have already seen, is another example of this design trend.
bash arithmetic expressions are equivalent to their counterparts in the Java and C languages.[9] Precedence and associativity are the same as in C. Table 6-2 shows the arithmetic operators that are supported. Although some of these are (or contain) special characters, there is no need to backslash-escape them, because they are within the $((...)) syntax.
Table 6-2. Arithmetic operators
Operator
Meaning
++
Increment by one (prefix and postfix)
—
Decrement by one (prefix and postfix)
+
Plus
-
Minus
*
Multiplication
/
Division (with truncation)
%
Remainder
**
Exponentiation[10]
<<
Bit-shift left
>>
Bit-shift right
&
Bitwise and
|
Bitwise or
~
Bitwise not
!
Logical not
^
Bitwise exclusive or
,
Sequential evaluation
[10] Note that ** is not in the C language.
The ++ and - operators are useful when you want to increment or decrement a value by one.[11] They work the same as in Java and C, e.g., value++ increments value by 1. This is called post-increment; there is also a pre-increment: ++value. The difference becomes evident with an example:
$ i=0
$ echo $i
0
$ echo $((i++))
0
$ echo $i
1
$ echo $((++i))
2
$ echo $i
2
In both cases the value has been incremented by one. However, in the first case (post-increment) the value of the variable was passed to echo and then the variable was incremented. In the second case (pre-increment) the increment was performed and then the variable passed to echo.
Parentheses can be used to group subexpressions. The arithmetic expression syntax also (as in C) supports relational operators as "truth values" of 1 for true and 0 for false. Table 6-3 shows the relational operators and the logical operators that can be used to combine relational expressions.
Table 6-3. Relational operators
Operator
Meaning
<
Less than
>
Greater than
<=
Less than or equal to
>=
Greater than or equal to
==
Equal to
!=
Not equal to
&&
Logical and
||
Logical or
For example, $((3 > 2)) has the value 1; $(( (3 > 2) || (4 <= 1) )) also has the value 1, since at least one of the two subexpressions is true.
The shell also supports base N numbers, where N can be from 2 to 36. The notation B # N means "N base B". Of course, if you omit the B #, the base defaults to 10.