概念:shell 中的运算符主要有比较运算(用于整数比较),字符串运算,文件操作运算,逻辑运算符,算术运算符,位运算符,自增自减运算符等,接下来详细讲述一下shell中的算术运算的方法。
算术运算 | 含义 |
+、- | 加法,减法 |
*、/、% | 乘法,除法,取余 |
** | 幂,次方 |
++、-- | 自增,自减,可以放到变量前或者变量后 |
!、&&、|| | 逻辑符号,与或非 |
<、<=、>、>= | 比较符号。小于,小于等于,大于,大于等于 |
==、!=、= | 等于,不等于 |
<<、>> | 向左向右移位 |
~ 、|、 & 、^ | 按位取反,或,与异或 |
=、+=、-=、*=、/=、%=、 | 赋值符号,a+=1,b-=1,c*=1 |
如果直接输出两个数相加、相乘、相除。可以很明显的看到,算术没有被计算,而是当成字符串被输出了。说明:shell编程与其他编程不同,shell不能直接进行算术运算,必须使用计算命令,而是把运算符号两边的数字当成字符串,把运算符号也当成字符串。最终形成一个新字符串 。
[root@YJW ~]# echo 1+1
1+1
[root@YJW ~]# echo 2*2
2*2
[root@YJW ~]# echo 2/6
2/6
但是在某些时候我们需要在命令中或者在shell脚本中计算变量的值,那么该怎么办呢?可以使用以下数学计算命令,在shell中有六种常用的算术计算方法。
运算符 | 说明 |
---|---|
(()) | 用于整数运算,效率很高 |
let | 用于整数运算,和(())类似 |
$[] | 用于整数运算,不如(())灵活 |
expr | 用于整数运算,也可处理字符串,比较麻烦,不推荐使用 |
bc | 可以处理整数,也可以处理小数,shell本身支持整数原酸 |
declare-i | 将变量定义为整数,然后再进行数学运算时就不会被当做字符串了。功能有限,仅支持最基本的数学运算(加减乘除和取余),不支持逻辑运算、自增自减等,所以在实际开发中很少使用。 |
1、位运算
位运算是基于内存中二进制的数据的运算,常见的位运算有>>右移位,<<左移位,安位与、或、非、异或等运算,二进制中的100等于十进制中的4。
二进制 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
十进制 | 2^7 | 2^6 | 2^5 | 2^4 | 2^3 | 2^2 | 2^1 | 2^0 |
二进制 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
十进制 | 2^7 | 2^6 | 2^5 | 2^4 | 2^3 | 2^2 | 2^1 | 2^0 |
二进制 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
十进制 | 2^7 | 2^6 | 2^5 | 2^4 | 2^3 | 2^2 | 2^1 | 2^0 |
#左移右移运算
# 右移两位
[root@YJW ~]# let "value=4>>2"
[root@YJW ~]# echo $value
1
# 左移两位
[root@YJW ~]# let "value=4<<2"
[root@YJW ~]# echo $value
16
2、自增减
自增减运算主要包括前置自增减与后置自增减。
前置:先修改变量,然后在传递变量,例如:++a,--a
[root@YJW ~]# a=10
[root@YJW ~]# let "b=(++a)"
[root@YJW ~]# echo "a:$a,b:$b"
a:11,b:11
:<<EOF
a = a+1,
b=a
EOF
后置:先传递变量,在修改变量的值,例如:a++,a--
[root@YJW ~]# a=10
[root@YJW ~]# let "b=(a++)"
[root@YJW ~]# echo "a:$a,b:$b"
a:11,b:10
:<<EOF
b=a
a=a+1
EOF
3、使用 $[表达式] 做运算
$[]与$(())类似,可以做一些简单的数学运算。按常理说,'/' 反斜杠应该表示除法,不是整除,但是shell中得到的数是一个整数,应该的到2.5。shell中/运算是舍去了小数。$[]是不能做小数的算术运算的。
[root@YJW ~]# echo $[1+1] # 1 + 1
2
[root@YJW ~]# echo $[4*4] # 4乘于4
16
[root@YJW ~]# echo $[5/2] # 5整除2
2
[root@YJW ~]# echo $[5%2] # 5对2取余
1
[root@YJW ~]# echo $[5.0/2]
-bash: 5.0/2: syntax error: invalid arithmetic operator (error token is ".0/2")
4、使用 let "表达式" 做运算
let “表达式” 只能做一些简单的整数运算,和$(())类似,和$[]一样不能做小数的算术运算。
[root@YJW ~]# a=11
[root@YJW ~]# let "b=(a+3)"
[root@YJW ~]# echo $b
14
[root@YJW ~]# let "b=5.0/2"
-bash: let: b=5.0/2: syntax error: invalid arithmetic operator (error token is ".0/2")
5、使用 expr 表达式 做运算
expr 表达式,可以整数运算,也可以值字符串运算,但是在做乘法运算的时候需要加上\,转义符号,而且字符之间需要时候空格隔开。如果没有空格隔开只会当做一个字符。
[root@YJW ~]# clear
[root@YJW ~]# expr 5+2
5+2
[root@YJW ~]# expr 5 + 2
7
[root@YJW ~]# expr 5 * 2
expr: syntax error
[root@YJW ~]# expr 5 \* 2
10
[root@YJW ~]# expr 5 / 2
2
[root@YJW ~]# expr 5 % 2
1
[root@YJW ~]#
6、使用declare做运算
declare -i 是shell的内建命令,使用declare -i 做运算的方式是定义变量的方法。普通的变量创建输出的是一个字符串,但是如果使用declare -i 创建的变量,可以被解析成算术运算
[root@YJW ~]# a=5+2
[root@YJW ~]# echo $a
5+2
[root@YJW ~]# declare -i b=5+2
[root@YJW ~]# echo $b
7
[root@YJW ~]# declare -i b=5*2
[root@YJW ~]# echo $b
10
注意:shell中的算术运算要求符号与数字之间不能有空格,特殊符号在这也不需要使用转义符号,如果又变了也不需要使用$符号
7、算术扩展
1、$((表达式))双小括号,运用整数运算,效率很高,在第二个计算中没有变量c,但是数值也被计算出来了,若表达式中的变量没有定义,则在计算时,其值会被假设为0(但是并不会真的因此赋0值给该变量)。
[root@YJW ~]# i=5
[root@YJW ~]# echo $((2+i))
7
[root@YJW ~]# a=10
[root@YJW ~]# b=11
[root@YJW ~]# echo $((a*b+c))
110
2、使用bc 做运算,可以基于浮点数进行计算,前面的5中方法只能基于整数,bc也是Linux中一款专门用于高精度计算的工具。与其说bc是一个命令或者工具,不如说它是一门语言,bc的man文件对它的描述是:“一款高精度计算语言(An arbitrary precision calculator language),但是bc不是每个操作系统中都存在的。
[root@YJW ~]# bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
a=1.0
b=3.0
a+b
4.0
44+55
99
5/2
2
scale=3
5/2
2.500
在shell命令中使用bc计算,可以使用管道符,来将变量传递个bc,使其计算。这种计算方法很是简洁,不用再启动bc
[root@YJW ~]# echo "2.0*3.500" | bc
7.000
[root@YJW ~]# echo "100/2" | bc
50
[root@YJW ~]#
总结:在实际的工作或者shell学一种一般只需要掌握只学习$(())跟bc即可,不需要学习其它的,$(())用于整数运算,bc用于小数运算.其他的都基本上跟$(())类似。