((...))语法可以进行整数的算术运算。支持的算术运算符如下:
+:加法-:减法*:乘法/:除法(整除)%:余数**:指数++:自增运算(前缀或后缀)--:自减运算(前缀或后缀)1 | # ((...))会自动忽略内部的空格,所以写不写空格都可以 |
注意:
5除以2,得到的结果是2,而不是2.5。++和--这两个运算符有前缀和后缀的区别。作为前缀是先运算后返回值,作为后缀是先返回值后运算。$((...))结构可以嵌套,$((...))内部支持用圆括号改变运算顺序。$((...))的圆括号之中,不需要在变量名之前加上$,不过加上也不报错。如果不存在同名变量,Bash 就会将其作为空值。$[...]也可以做整数运算,是以前的语法,不建议使用。Bash 的数值默认都是十进制,但是在((...))中,也可以使用其他进制,然后可以使用$把双括号中其他进制的数值转换为默认的10进制数
number:没有任何前缀的是默认的十进制数。0number:以0开头,后面的数字会被认为是八进制数。0xnumber:以0x开头,后面的数字会被认为是十六进制数。base#number:以base#开头,base代表任意数字,比如3#,后面的数字会被认为是base进制的数。下面是一些例子:
1 | $ echo $((0xff)) |
$((...))支持以下的二进制位运算符。本质上是将10进制数转化为2进制数,进行位运算之后,再转化为10进制数。
<<:位左移运算,把一个数字的所有位向左移动指定的位。>>:位右移运算,把一个数字的所有位向右移动指定的位。&:位的“与”运算,对于两个数字的每个位,都为1则结果为1,否则结果为0|:位的“或”运算,对于两个数字的每个位,只要有一个为1,则结果为1^:位的异或运算(exclusive or),对于两个数字的每个位,不同为1,相同为0~:位的“否”运算,对一个数字的所有位取反。1 | # 将16(二进制`10000`)的所有位向左移动2位,变成了4(二进制`100`) |
$((...))支持以下的逻辑运算符。
<:小于>:大于<=:小于或相等>=:大于或相等==:相等!=:不相等&&:逻辑与||:逻辑或!:逻辑否expr1?expr2:expr3:三元条件运算符。若expr1的计算结果为非零值(算术真),则执行expr2,否则执行expr3。1 | # 如果逻辑表达式为真,返回1,否则返回0 |
$((...))可以执行赋值运算,同时这个式子本身也是一个表达式,返回值就是运算后的值。
$((...))支持的赋值运算符,有以下这些。
parameter = value:简单赋值。parameter += value:等价于parameter = parameter + value。parameter -= value:等价于parameter = parameter – value。parameter *= value:等价于parameter = parameter * value。parameter /= value:等价于parameter = parameter / value。parameter %= value:等价于parameter = parameter % value。parameter <<= value:等价于parameter = parameter << value。parameter >>= value:等价于parameter = parameter >> value。parameter &= value:等价于parameter = parameter & value。parameter |= value:等价于parameter = parameter | value。parameter ^= value:等价于parameter = parameter ^ value。下面是一个例子。
1 | $ foo=5 |
逗号,在$((...))内部是求值运算符,执行前后两个表达式,并返回后一个表达式的值。
1 | $ echo $((foo = 1 + 2, 3 * 4)) |
上面例子中,逗号前后两个表达式都会执行,然后返回后一个表达式的值12。
expr命令支持算术运算,可以不使用((...))语法。
1 | $ expr 3 + 2 |
expr命令支持变量替换。
1 | $ foo=3 |
注意:expr命令也只支持整数运算
let命令用于将算术运算的结果,赋予一个变量。
1 | $ let x=2+3 |
注意,x=2+3这个式子里面不能有空格,否则会报错。let命令的详细用法参见《变量》一章。