五、Shell的变量之五变量的算数运算
+、- 加法(或正号)、减法(或符号) *、/、% 乘法、除法、取余(取模) ** 幂运算 ++、—— 增加及减少,可前置也可放在变量结尾 !、&&、|| 逻辑非(取反)、逻辑与(and)、逻辑或(or) <、<=、>、>= 比较符号(小于、小于等于、大于、大于等于) ==、!=、= 比较符号(相等、不等于,对于字符串"=="表示相当于) <<、>> 向左移位、向有移位 ~、|、&、^ 按位取反、按位异或、按位与、按位或 =、+=、-=、*=、/=、%= 赋值运算符,如a+=1相当于a=a+1,a-=1相当于a=a-1
(()) 用于整数运算的常用运算符,效率很高 let 用于整数运算,类似于"(())" expr 可用于整数运算,但也有很多其他的额外功能 bc Linux下的一个计算器程序(适合整数和小数运算) $[] 用于整数运算 awk 即可以用于整数计算,也可以用于小数计算 declare 定义变量值和属性,-i参数可以用于定义整形变量,做运算
1、双小括号"(())"
"(())"的运算
((i=i+1)) 运算后赋值法,即将i+1的值赋值给i,不能用"echo ((i=i+1))"的形式输出表达式的值,但可以用"echo $((i=i+1))"输出其值。 [root@node1 ~]# echo ((i=7+6)) -bash: syntax error near unexpected token `(' #上面为错误的输出 [root@node1 ~]# echo $((i=7+6)) 13 [root@node1 ~]# ((a=1+2**3-4%3)) [root@node1 ~]# echo $a 8 等价于 [root@node1 ~]# echo $((1+2**3-4%3)) 8 [root@node1 ~]# a=10 [root@node1 ~]# echo $((a**2)) 100
特殊运算符号
[root@node1 ~]# echo $a 8 [root@node1 ~]# echo $((1+2**3-4%3)) 8 [root@node1 ~]# a=8 [root@node1 ~]# echo $((a=a+1)) 9 [root@node1 ~]# echo $((a+=1)) #====echo $((a=a+1)) 10
"(())"的比较及判断
"(())"的比较,真值为1,假值为0 [root@node1 ~]# echo $((3<8)) 1 [root@node1 ~]# echo $((3>8)) 0 [root@node1 ~]# echo $((3==3)) 1 判断 [root@node1 ~]# if((8>7&&5==5)) > then > echo yes > fi yes #如果8>7且5==5,则打印yes
++的特殊运算表达式
[root@node1 ~]# a=10 [root@node1 ~]# echo $((a++)) 10 [root@node1 ~]# echo $a 11 #执行完表达式后,a会自增1,再把值赋值给a [root@node1 ~]# a=10 [root@node1 ~]# echo $((a--)) 10 [root@node1 ~]# echo $a 9 #执行完表达式后,a会自减1,再把值赋值给a [root@node1 ~]# a=10 [root@node1 ~]# echo $((++a)) 11 [root@node1 ~]# echo $a 11 #先给a增加1,再执行表达式 [root@node1 ~]# a=10 [root@node1 ~]# echo $((--a)) 9 [root@node1 ~]# echo $a 9 #先给a减少1,再执行表达式
++、——运算的记忆方法:
变量a在运算符之前,输出表达式的值为a,然后a自增或自减;变量a在运算符之后,输出表达式会先自增或自减,表达式的值就是自增或自减后a的值。
运算后赋值给变量
[root@node1 ~]# a=10 [root@node1 ~]# a=$((a+1)) [root@node1 ~]# echo $a 11
1) "(())"表达式在命令行执行时不需要加$符号,直接使用((6%2))形式即可,但是如果需要输出,就要加$符,例如:echo $((6%2))。 2) "(())"里的所有字符之间没有空格、有一个或多个空格都不会影响结果。
各种"(())"运算的shell脚本案例
#!/bin/bash a=6 #<==在脚本中定义a和b两个变量并分别赋值。 b=2 echo "a-b=$(($a-$b))" #<==对定义的变量值进行各种符号运算,并通过表达式的形式输出,下同。 echo "a+b=$(($a+$b))" echo "a*b=$(($a*$b))" echo "a/b=$(($a/$b))" echo "a**b=$(($a**$b))" echo "a%b=$(($a%$b))" 结果 a-b=4 a+b=8 a*b=12 a/b=3 a**b=36 a%b=0
let运算命令的语法格式为:let赋值表达式
let赋值表达式的功能等同于“((赋值表达式))”
[root@node1 ~]# a=10 [root@node1 ~]# let a=a+2 [root@node1 ~]# echo $a 12 相当于 [root@node1 ~]# a=10 [root@node1 ~]# a=$((a+2)) [root@node1 ~]# echo $a 12
expr用于计算
[root@node1 ~]# expr 2 + 2 4 [root@node1 ~]# expr 2 * 2 expr: syntax error [root@node1 ~]# expr 2 \* 2 4 [root@node1 ~]# expr 2 / 2 1 [root@node1 ~]# expr 2 % 2 0 要注意,在使用expr时: ·运算符及用于计算的数字左右都至少有一个空格,否则会报错。 ·使用乘号时,必须用反斜线屏蔽其特定含义,因为Shell可能会误解星号的含义。
expr在Shell中可配合变量进行计算,但需要用反引号将计算表达式括起来
[root@node1 ~]# a=10 [root@node1 ~]# b=`expr $a + 6` [root@node1 ~]# echo $b 16
判断一个变量值或字符串是否为整数
实现原理是,利用以expr做计算时变量或字符串必须是整数的规则,把一个变量或字符串和一个已知的整数(非0)相加,看命令返回的值是否为0。如果为0,就认为做加法的变量或字符串为整数,否则就不是整数。 [root@node1 ~]# i=5 [root@node1 ~]# expr $i + 6 &>/dev/null [root@node1 ~]# echo $? 0 [root@node1 ~]# i=kaka [root@node1 ~]# expr $i + 6 &>/dev/null [root@node1 ~]# echo $? 2 #利用expr做计算,将一个未知的变量和一个已知的整数相加,看返回值是否为0,如果为0就认为做加法的变量为整数,否则就不是整数。
通过传参判断输出内容是否为整数
[root@node1 tmp]# cat expr.sh #!/bin/sh expr $1 + 1 >/dev/null 2>&1 [ $? -eq 0 ] &&echo int||echo chars #<==这是一个条件表达式语法,返回值为0,则输出int,否则输出chars。
[root@node1 tmp]# sh /tmp/expr.sh 5 int [root@node1 tmp]# sh /tmp/expr.sh kaka chars
expr的特殊用法:判断文件扩展命名是否符合要求
[root@node1 tmp]# cat expr1.sh #!/bin/sh if expr "$1" : ".*\.pub" &>/dev/null then echo "you are using $1" else echo "pls use *.pub file" fi
[root@node1 tmp]# sh expr1.sh kaka pls use *.pub file [root@node1 tmp]# sh expr1.sh king.pub you are using king.pub
通过expr计算字符串的长度
[root@node1 tmp]# a="ni hao da hai" [root@node1 tmp]# expr length "$a" 13 #包含空格
将bc作为计算器来应用
[root@node1 tmp]# 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'. 1+1 2
[root@node1 tmp]# echo 3+4|bc 7 [root@node1 tmp]# echo 3.3+4|bc 7.3 [root@node1 tmp]# echo 8.3+4.7|bc 13.0 [root@node1 tmp]# echo 8.3-4.7|bc 3.6 [root@node1 tmp]# echo "scale=2;8.3-4.7"|bc 3.6 [root@node1 tmp]# echo "scale=2;8.3/4.7"|bc 1.76 [root@node1 tmp]# echo "scale=6;355/113"|bc #scale保留小数点后几位 3.141592
利用bc配合变量运算
[root@node1 tmp]# i=5 [root@node1 tmp]# i=`echo $i+6|bc` [root@node1 tmp]# echo $i 11
利用awk进行运算的效果也很好,适合小数和整数,特别是命令行计算,尤其是小数,运算很精确 [root@node1 tmp]# echo "7.8 4.5"|awk '{print ($1-$2)}' 3.3 [root@node1 tmp]# echo "358 113" |awk '{print ($1-3)/$2}' 3.14159 [root@node1 tmp]# echo "3 9" |awk '{print ($1+3)*$2}' 54
[root@node1 tmp]# declare -i A=30 B=7 #<==declare -i参数可以将变量定义为整形。 [root@node1 tmp]# A=A+B #<==因为已声明是整型,因此可以直接进行运算了。 [root@node1 tmp]# echo $A 37 #<==结果为37
[root@node1 tmp]# i=5 [root@node1 tmp]# i=$[i+6] [root@node1 tmp]# echo $i 11 [root@node1 tmp]# echo $[2*3] 6 [root@node1 tmp]# echo $[2**3] 8 [root@node1 tmp]# echo $[3/5] 0 [root@node1 tmp]# echo $[3/2] 1 [root@node1 tmp]# echo $[3%5] 3 [root@node1 tmp]# echo $[ 3 % 5 ] 3
Shell变量除了可以直接赋值或脚本传参外,还可以使用read命令从标准输入中获得,read为bash内置命令,可通过help read查看帮助。 语法格式:read[参数][变量名] 常用参数如下。 ·-p prompt:设置提示信息。 ·-t timeout:设置输入等待的时间,单位默认为秒。
实现read的基本读入功能。
[root@node1 tmp]# read -t 10 -p "Pls input one num:" num #<==读入一个输入,赋值给num变量,注意,num变量前需要有空格。 Pls input one num:18 #<==输出数字18,相当于把18赋值给num变量。 [root@node1 tmp]# echo $num #<==输出变量值。 [root@node1 tmp]# read -p "please input two number:" a1 a2 #<==读入两个输入,注意要以空格隔开,分别赋值给a1和a2变量,a1变量前后都需要有空格。 please input two number:1 2 [root@node1 tmp]# echo $a1 1 [root@node1 tmp]# echo $a2 2
把前面加减乘除计算传参的脚本改成通过read方式读入整数变量
#!/bin/bash read -t 15 -p "please input two number:" a b #<==去掉原脚本中a和b的定义,通 过read读入即可。 echo "a-b=$(($a-$b))" echo "a+b=$(($a+$b))" echo "a*b=$(($a*$b))" echo "a/b=$(($a/$b))" echo "a**b=$(($a**$b))" echo "a%b=$(($a%$b))"
I have a dream so I study hard!!!