Shell中的运算符主要有比较运算符(用于整数比较)、字符串运算符(用于字符串测试)、文件操作运算符(用于文件测试)、逻辑运算符、算术运算符、位运算符、自增自减运算符等。
算术运算符指的是加、减、乘、除、余、幂等常见的算术运算,以及加等、减等、乘等、除等、余等复合算术运算。要特别注意的是,Shell只支持整数计算,也就是所有可能产生小数的运算都会舍去小数部分。
常见的算术运算大多需要结合Shell的内建命令let来使用。
位运算是基于内存中二进制数据的运算,也就是基于位的运算。常见的位运算有左移运算、右移运算、按位与、按位或、按位非、按位异或等运算。
位运算的左移、右移元素其实就是整数在内存中的“左右移动”,其中左移运算符为<<,右移运算符为>>。
#左移右移运算
#4左移2
[root@localhost ~]# let "value=4<<2"
[root@localhost ~]# echo $value
16
#4右移2
[root@localhost ~]# let "value=4>>2"
[root@localhost ~]# echo $value
1
按位与运算==(&)==,是将两个整数写成二进制的形式,然后同位置相比较,只有当对应的二进制值都为1时,结果才为1。
#按位与运算
[root@localhost ~]# let "value=8&4"
[root@localhost ~]# echo $value
0
按位或运算==(|)==,是将两个整数写成二进制的形式,然后同位置相比较,只要对应的位置有1,结果就为1。
#按位或运算
[root@localhost ~]# let "value=8|4"
[root@localhost ~]# echo $value
12
按位异或运算==(^)==,是将两个整数写成二进制的形式,然后同位置相比较,只要对应的位置同为0或同为1,结果就为0,否则为1。
#按位异或运算
[root@localhost ~]# let "value=10^3"
[root@localhost ~]# echo $value
9
按位非==(~)==的计算方式比较麻烦,这里有个快捷的计算公式:“~a”的值为“-(a+1)”。
#按位非运算
[root@localhost ~]# let "value=~8"
[root@localhost ~]# echo $value
-9
**自增自减运算主要包括前置自增、前置自减、后置自增、后置自减等。**自增符为“++”,自减符为“–”,操作对象只能是变量,不能是常数或表达式。
[root@localhost ~]# cat add_minus.sh
#!/bin/bash
Add_01=10
Add_02=10
#Add_01前置自增
#也就是先将Add_01自增1变为11,然后赋值给Add_03,即为11
let "Add_03=(++Add_01)"
#Add_02后置自增
#也就是先将当前值赋给Add_04,即10,然后Add_02自增1,即为11
let "Add_04=(Add_02++)"
#打印各变量的值
#按照上面的计算方式,Add_01、Add_02、Add_03为11,Add_04为10
echo Add_01 is:$Add_01
echo Add_02 is:$Add_02
echo Add_03 is:$Add_03
echo Add_04 is:$Add_04
[root@localhost ~]# bash add_minus.sh
Add_01 is:11
Add_02 is:11
Add_03 is:11
Add_04 is:10
$[]和$(())类似,可用于简单的算术运算,以下给出使用方式:
[root@localhost ~]# echo $[1+1]
2
[root@localhost ~]# echo $[2-1]
1
[root@localhost ~]# echo $[2*2]
4
#除法运算,由于是整数操作,舍去小数
[root@localhost ~]# echo $[5/2]
2
#求余运算
[root@localhost ~]# echo $[5%2]
1
#幂运算
[root@localhost ~]# echo $[5**2]
25
##2.使用expr做运算
expr命令也可用于整数运算。和其他算术运算方式不同,expr要求操作数和操作符之间使用空格隔开(否则只会打印出字符串),所以特殊的操作符要使用转义符转义(比如*)。
#操作符和操作数之间没有空格则只会打印出字符串
[root@localhost ~]# expr 1+1
1+1
#使用空格隔开后可以正常计算
[root@localhost ~]# expr 1 + 1
2
#特殊符号(元字符)需要用转义符转义,否则出错
[root@localhost ~]# expr 2 * 2
expr: syntax error
[root@localhost ~]# expr 2 \* 2
4
#例1:不使用declare定义变量
[root@localhost ~]# I=1+1
[root@localhost ~]# echo $I
1+1
#例2:使用declare定义变量
[root@localhost ~]# declare-i J
[root@localhost ~]# J=1+1
[root@localhost ~]# echo $J
2
#注意,Shell中的算术运算要求运算符和操作数之间不能有空格,而是紧密连接的;特殊符号在这里也不需要用转义符转义(比如这里的+号);如果算术表达式中含有其他变量也不需要用$引用
例1里的变量I未经正式定义便赋值“1+1”,对Shell来说,此时的“1+1”只是一个字符串,和“abc”无异,所以打印出来也只是字符串。
例2中,使用declare显式地定义了整数变量J==(-i参数指定变量为“整数”)==,此时再赋值“1+1”,Shell会将后面的字符串解析成算术运算,所以打印出的值是算术表达式的计算值。
算术扩展是Shell提供的整数变量的运算机制,是Shell的内建命令之一。其基本语法如下:
$((算术表达式))
#显示输出:
echo $((算术表达式))
#例子:计算2*i+1的值
[root@localhost ~]# i=2
[root@localhost ~]# echo $((2*i+1)) #注意这里变量i前并没有$符
5
[root@localhost ~]# echo $((2*(i+1))) #用括号改变运算优先级
6
#变量赋值
var=$((算术表达式))
#例子:将2*i+1的值赋值给变量var
[root@localhost ~]# var=$((2*i+1))
[root@localhost ~]# echo $var
5
#未定义的变量参与算术表达式求值
#若表达式中的变量没有定义,则在计算时,其值会被假设为0(但是并不会真的因此赋0值给该变量)
[root@localhost ~]# echo $((2*(j+1)))
2
Linux下的bc正是这样一款专门用于高精度计算的工具。bc的man文件对它的描述是:“一款高精度计算语言(An arbitrary precision calculatorlanguage)”。
在Linux下使用bc最简单的方式是直接输入bc命令,回车后进入bc的交互式界面,闪烁的命令提示符表明现在可以输入表达式了。
[root@localhost ~]# bc
bc 1.06
Copyright 1991-1994,1997,1998,2000 Free Software Foundation,Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
a=9
b=5
a+b
14
a-b
4
a*b
45
a/b
1
#事实上,默认情况下bc并不显示小数部分,必须设置要显示的小数位数。
#设置显示的小数位数
scale=3
a/b
1.800
除此之外,bc还支持逻辑运算、比较运算。但是在Shell编程中,往往只需要调用bc的处理结果而不会进入bc的交互界面。好在bc已经考虑到了这种情况,所以它支持批量的处理和以管道方式处理表达式计算。
[root@localhost ~]# cat cal.bc
12*34
34/12
scale=3;34/12
a=1;b=2;a+b
#批量计算
[root@localhost ~]# cat cal.bc | bc
408
2
2.833
3
#直接调用bc计算表达式,并将计算结果赋值给变量以参与后面的计算或判断。
[root@localhost ~]# cat bc.sh
#!/bin/bash
NUM01=10
NUM02=15
TOTAL=$(echo "$NUM01+$NUM02" | bc)
echo $TOTAL
[root@localhost ~]# bash bc.sh
25
关于bc的更多用法可以参考man文件。bc更是一门语言,它有和常规编程语言一样的支持顺序执行、判断、循环等运行机制,还支持自定义函数等,功能非常强大,有兴趣的读者可以深入了解。