Shell入门-Shell变量数值计算
Shell变量数值计算
算术运算符
Shell中常见的算术运算符号
+
:加法-
:减法或负号*
:乘法/
:除法%
:取余**
:幂运算++
:增加--
:减少!
:逻辑非&&
:逻辑与||
:逻辑或< <= > >=
:比较符号== != =
:比较符号,对于字符串“=”也可以表示相当于<< >>
:向左移位、向右移位~
:按位取反|
:按位异或&
:按位与^
:按位或= += -= *= /= %=
:赋值运算
算术运算命令
(())
:用于整数运算let
:用于整数运算,类似于(())
expr
:用于整数运算bc
:适合整数及小数运算$[]
:用于整数运算awk
:适合整数及小数运算declare
:定义变量值和属性
(())
双小括号(())
的作用是进行数值运算与数值比较。
简单的数值运算:
[root@localhost shell]# echo $((1+1))
2
[root@localhost shell]# echo $((6-3))
3
[root@localhost shell]# ((i=5))
[root@localhost shell]# ((i=i*2))
[root@localhost shell]# echo $i
10
[root@localhost shell]#
复杂的综合运算
[root@localhost shell]# ((a=1+2**3-4%3))
[root@localhost shell]# echo $a
8
[root@localhost shell]# b=$((1+2**3-4%3))
[root@localhost shell]# echo $b
8
[root@localhost shell]# echo $((1+2**3-4%3))
8
[root@localhost shell]# a=$((100*(100+1)/2))
[root@localhost shell]# echo $a
5050
[root@localhost shell]# echo $((100*(100+1)/2))
5050
[root@localhost shell]#
特殊运算符号
[root@localhost shell]# a=8
[root@localhost shell]# echo $((a=a+1))
9
[root@localhost shell]# echo $((a+=1))
10
[root@localhost shell]# echo $((a**2))
100
比较及判断
[root@localhost shell]# echo $((3<8))
1
[root@localhost shell]# echo $((8<3))
0
[root@localhost shell]# echo $((8=8))
-bash: 8=8: 尝试给非变量赋值 (错误符号是 "=8")
[root@localhost shell]# echo $((8==8))
1
[root@localhost shell]# if ((8>7&&5==5))
> then
> echo yes
> fi
yes
[root@localhost shell]#
++ --
的使用,和Java中的类似
[root@localhost shell]# a=10
[root@localhost shell]# echo $a
10
[root@localhost shell]# echo $((a++))
10
[root@localhost shell]# echo $a
11
[root@localhost shell]# echo $((a--))
11
[root@localhost shell]# echo $a
10
[root@localhost shell]# echo $((++a))
11
[root@localhost shell]# echo $a
11
[root@localhost shell]# echo $((--a))
10
[root@localhost shell]# echo $a
10
[root@localhost shell]#
总结:
(())
表达式在命令行执行时不需要加$
符号,直接使用((6%2))
形式即可,但是如果需要输出,就要加$
符,例如:echo $((6%2))
。(())
里的所有字符之间没有空格、有一个或多个空格都不会影响结果
(())
使用实例:
[root@localhost shell]# cat test-arithmetic-001.sh
#!/bin/bash
#***********************************************
#Author: luotianhao
#Mail: tianhao.luo@hand-china.com
#Version: 1.0
#Date: 2021-03-08
#FileName: test-arithmetic-001.sh
#Description: This is a test script.
#***********************************************
a=6
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))"
[root@localhost shell]# sh test-arithmetic-001.sh
a-b=4
a+b=8
a*b=12
a/b=3
a**b=36
a%b=0
我们可以改造上面的脚本,通过命令行传参,修改变量的取值来源:
[root@localhost shell]# cat test-arithmetic-001.sh
#!/bin/bash
#***********************************************
#Author: luotianhao
#Mail: tianhao.luo@hand-china.com
#Version: 1.0
#Date: 2021-03-08
#FileName: test-arithmetic-001.sh
#Description: This is a test script.
#***********************************************
a=$1
b=$2
c=$#
if [ 2 -ne $c ]
then
echo "please input two args"
exit
fi
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))"
[root@localhost shell]# sh test-arithmetic-001.sh
please input two args
[root@localhost shell]# sh test-arithmetic-001.sh 6 2
a-b=4
a+b=8
a*b=12
a/b=3
a**b=36
a%b=0
let
- let运算命令的语法格式为:let赋值表达式
- let赋值表达式的功能等同于
((赋值表达式))
[root@localhost shell]# i=2
[root@localhost shell]# i=i+8
[root@localhost shell]# echo $i
i+8
[root@localhost shell]# unset i
[root@localhost shell]# i=2
[root@localhost shell]# let i=i+8
[root@localhost shell]# echo $i
10
[root@localhost shell]#
创建一个脚本监控Web服务状态,如果访问两次都失败,则报警。
提示:实际上wget命令有自动重试的功能,--tries=1参数就是
[root@localhost shell]# vim $(date +%F)_checkurl.sh
[root@localhost shell]# cat 2021-03-08_checkurl.sh
#!/bin/bash
#***********************************************
#Author: luotianhao
#Mail: tianhao.luo@hand-china.com
#Version: 1.0
#Date: 2021-03-08
#FileName: 2021-03-08_checkurl.sh
#Description: This is a test script.
#***********************************************
checkUrl() {
#重试次数
timeout=5
#失败次数
fails=0
#成功次数
success=0
#默认死循环
while true
do
wget --timeout=$timeout --tries=1 http://10.185.62.161 -q -O /dev/null
#$?结果为0表示上一条命令执行结果成功
if [ $? -ne 0 ]
then
#不为0表示失败,失败次数+1
let fails=fails+1
else
#为0成功,成功次数+1
let success+=1
fi
#成功次数大于等于1,输出success,并退出
if [ $success -ge 1 ]
then
echo success
exit 0
fi
#失败次数大于等于2,输出错误信息,并退出
if [ $fails -ge 2 ]
then
Critical="sys is down..."
echo $Critical
exit 2;
fi
done
}
#执行上面定义的函数
checkUrl
监控执行结果:
[root@localhost shell]# sh -x 2021-03-08_checkurl.sh
+ checkUrl
+ timeout=5
+ fails=0
+ success=0
+ true
+ wget --timeout=5 --tries=1 http://10.185.62.161 -q -O /dev/null
+ '[' 0 -ne 0 ']'
+ let success+=1
+ '[' 1 -ge 1 ']'
+ echo success
success
+ exit 0
expr
expr的用途
- 整数运算
- 相关字符串长度、匹配等运算处理
1.expr用于计算
语法:expr Expression
[root@localhost shell]# expr 2+2
2+2
[root@localhost shell]# expr 2 + 2
4
[root@localhost shell]# expr 2 * 2
expr: 语法错误
[root@localhost shell]# expr 2 \* 2
4
[root@localhost shell]# expr 2 / 2
1
[root@localhost shell]#
注意事项:
- 运算符及用于计算的数字左右都至少有一个空格,否则会报错。
- 使用乘号时,必须用反斜线屏蔽其特定含义,因为Shell可能会误解星号的含义。
2.expr配合变量计算
expr在Shell中可配合变量进行计算,但需要用反引号将计算表达式括起来。
[root@localhost shell]# i=5
[root@localhost shell]# i=`expr $i + 6`
[root@localhost shell]# echo $i
11
[root@localhost shell]#
使用expr来判断一个字符串是否为整数,原理是利用以expr做计算时变量或字符串必须是整数的规则,把一个变量或字符串和一个已知的整数(非0)相加,看命令返回的值是否为0。如果为0,就认为做加法的变量或字符串为整数,否则就不是整数。
[root@localhost shell]# i=5
[root@localhost shell]# expr $i + 6 &>/dev/null #<== &>/dev/null表示不保留任何输出
[root@localhost shell]# echo $?
0
[root@localhost shell]# i=oldboy
[root@localhost shell]# expr $i + 6 &>/dev/null
[root@localhost shell]# echo $?
2
[root@localhost shell]#
判断输出内容是否为空
[root@localhost shell]# vim $(date +%F)_expr.sh
[root@localhost shell]# cat 2021-03-08_expr.sh
#!/bin/bash
#***********************************************
#Author: luotianhao
#Mail: tianhao.luo@hand-china.com
#Version: 1.0
#Date: 2021-03-08
#FileName: 2021-03-08_expr.sh
#Description: This is a test script.
#***********************************************
expr $1 + 1 >/dev/null 2>&1
[ $? -eq 0 ] &&echo int||echo chars
[root@localhost shell]# sh 2021-03-08_expr.sh oldboy
chars
[root@localhost shell]# sh 2021-03-08_expr.sh 11
int
编写一个输入两个参数进行计算的程序,并且能判断传参个数和通过expr判断传入的参数是否为整数。
[root@localhost shell]# cat calculate_expr.sh
#!/bin/bash
#***********************************************
#Author: luotianhao
#Mail: tianhao.luo@hand-china.com
#Version: 1.0
#Date: 2021-03-08
#FileName: calculate_expr.sh
#Description: This is a test script.
#***********************************************
a=$1
b=$2
c=$#
if [ 2 -ne $c ]
then
echo "please input two args..."
exit 1;
fi
for i in $*;
do
expr $i + 1 > /dev/null 2>&1
if [ $? -eq 0 ]
then
echo "$i is int"
else
echo "$i is chars,please retry and input int"
exit 1;
fi
done
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))"
通过expr计算字符串的长度
[root@localhost shell]# char="i am oldboy"
[root@localhost shell]# expr length "$char"
11
[root@localhost shell]# echo ${#char}
11
[root@localhost shell]# echo ${char}|wc -L
11
[root@localhost shell]# echo ${char}|awk 'print length($0)'
awk: cmd. line:1: print length($0)
awk: cmd. line:1: ^ syntax error
[root@localhost shell]# echo ${char}|awk 'print length($O)'
awk: cmd. line:1: print length($O)
awk: cmd. line:1: ^ syntax error
[root@localhost shell]# echo ${char}|awk '{print length($0)}'
11
打印下面语句中字符数不大于6的单词:I am oldboy linux welcome to our training
。注意被循环的语句,不能用“”包裹
[root@localhost shell]# cat word_length.sh
#!/bin/bash
#***********************************************
#Author: luotianhao
#Mail: tianhao.luo@hand-china.com
#Version: 1.0
#Date: 2021-03-08
#FileName: word_length.sh
#Description: This is a test script.
#***********************************************
for n in "i am oldboy linux welcome to our training"
do
if [ `expr length $n` -le 6 ]
then
echo $n
fi
if [ ${#n} -le 6 ]
then
echo $n
fi
[root@localhost shell]# sh word_length.sh
expr: 语法错误
word_length.sh: 第 13 行:[: -le: 期待一元表达式
[root@localhost shell]# cat word_length.sh
#!/bin/bash
#***********************************************
#Author: luotianhao
#Mail: tianhao.luo@hand-china.com
#Version: 1.0
#Date: 2021-03-08
#FileName: word_length.sh
#Description: This is a test script.
#***********************************************
for n in i am oldboy linux welcome to our training
do
if [ `expr length $n` -le 6 ]
then
echo $n
fi
if [ ${#n} -le 6 ]
then
echo $n
fi
[root@localhost shell]# sh word_length.sh
i
i
am
am
oldboy
oldboy
linux
linux
to
to
our
our
获取expr的帮助:
[root@localhost shell]# man expr
[root@localhost shell]#
bc
bc是UNIX/Linux下的计算器,因此,除了可以作为计算器来使用,还可以作为命令行计算工具使用。
[root@localhost shell]# 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
3*3
9
使用bc
实现整数和小数的运算
[root@localhost shell]# echo 3+5|bc
8
[root@localhost shell]# echo 3.3+5.5|bc
8.8
[root@localhost shell]# echo "scale=2;355/113"|bc
3.14
[root@localhost shell]# echo "scale=6;355/113"|bc
3.141592
[root@localhost shell]#
bc
配合变量运算
[root@localhost shell]# i=5
[root@localhost shell]# i=`echo $i+6|bc`
[root@localhost shell]# echo $i
11
提示:根据bc
所具有的特殊性来看,如果是小数,则选择bc
运算没有问题(老男孩推荐awk
);若是整数场景,可用(())
、let
、expr
等。
通过一条命令计算输出1+2+3+…+10
的表达式,并计算出结果,请使用bc
命令计算。
生成1+2+3+…+10
的方法有如下两种:
seq -s "+" 10
:seq是生成数字序列,-s是指定数字序列echo {1..10}|tr " " "+"
:{1..10}是生成以空格为间隔的数字序列,并交给tr将空格替换为+号
[root@localhost shell]# seq -s "+" 10
1+2+3+4+5+6+7+8+9+10
[root@localhost shell]# echo {1..10}|tr " " "+"
1+2+3+4+5+6+7+8+9+10
计算方法:
[root@localhost shell]# echo $(seq -s '+' 10)=`seq -s "+" 10|bc`
1+2+3+4+5+6+7+8+9+10=55
[root@localhost shell]# echo "`seq -s '+' 10`="$((`seq -s "+" 10`))
1+2+3+4+5+6+7+8+9+10=55
[root@localhost shell]# echo `seq -s '+' 10`=`seq -s "+" 10|xargs expr`
1+2+3+4+5+6+7+8+9+10=1+2+3+4+5+6+7+8+9+10
[root@localhost shell]# echo `seq -s '+' 10`=`seq -s " + " 10|xargs expr`
1+2+3+4+5+6+7+8+9+10=55
[root@localhost shell]# echo `seq -s "+" 10`=$(echo $[`seq -s `])
seq:选项需要一个参数 -- s
Try 'seq --help' for more information.
1+2+3+4+5+6+7+8+9+10=0
[root@localhost shell]# echo `seq -s "+" 10`=$(echo $[`seq -s "+" 10`])
1+2+3+4+5+6+7+8+9+10=55
awk
利用awk进行运算的效果也很好,适合小数和整数,特别是命令行计算,尤其是小数,运算很精确,好用。
[root@localhost shell]# echo "7.7 3.8"|awk '{print ($1-$2)}'
3.9
[root@localhost shell]# echo "358 113"|awk '{print ($1-3)/$2}'
3.14159
[root@localhost shell]# echo "3 9"|awk '{print ($1+3)*$2}'
54
[root@localhost shell]#
declare(同typeset)
declare -i 参数可以将变量定义为整形。
[root@localhost shell]# declare -i A=30 B=7
[root@localhost shell]# A=A+B
[root@localhost shell]# echo $A
37
[root@localhost shell]#
$[]
[root@localhost shell]# i=5
[root@localhost shell]# i=$[i+6]
[root@localhost shell]# echo $i
11
[root@localhost shell]# echo $[2*3]
6
[root@localhost shell]# echo $[2**3]
8
[root@localhost shell]# echo $[3/5]
0
[root@localhost shell]# echo $[3/2]
1
[root@localhost shell]# echo $[3%5]
3
[root@localhost shell]# echo $[ 3 % 5 ]
3
read命令
Shell变量除了可以直接赋值或脚本传参外,还可以使用read命令从标准输入中获得,read为bash内置命令,可通过help read查看帮助。
语法格式:read [参数] [变量名]
常用参数:
- -p prompt:设置提示信息。
- -t timeout:设置输入等待的时间,单位默认为秒。
[root@localhost shell]# read -t 10 -p "pls input one num:" num
pls input one num:1
[root@localhost shell]# echo $num
1
[root@localhost shell]# read -p "pls input two number"
pls input two number1
[root@localhost shell]# read -p "pls input two number" a1 a2
pls input two number1 2
[root@localhost shell]# echo $a1
1
[root@localhost shell]# echo $a2
2
[root@localhost shell]#
使用read来作为脚本的参数
[root@localhost shell]# cat calculate_read.sh
#!/bin/bash
#***********************************************
#Author: luotianhao
#Mail: tianhao.luo@hand-china.com
#Version: 1.0
#Date: 2021-03-08
#FileName: calculate_read.sh
#Description: This is a test script.
#***********************************************
read -t 5 -p "please input two number:" a b
if [ 0 -ne $? ]
then
echo "timeout,will exit....."
exit 1;
fi
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))"
[root@localhost shell]# sh calculate_read.sh
please input two number:1 2
a-b=-1
a+b=3
a*b=2
a/b=0
a**b=1
a%b=1
整合判断输入的是否为整数和输入的个数为2
[root@localhost shell]# cat calculate_read.sh
#!/bin/bash
#***********************************************
#Author: luotianhao
#Mail: tianhao.luo@hand-china.com
#Version: 1.0
#Date: 2021-03-08
#FileName: calculate_read.sh
#Description: This is a test script.
#***********************************************
read -t 5 -p "please input two number:" a b
if [ 0 -ne $? ]
then
echo "timeout,will exit....."
exit 1;
fi
[ ${#a} -le 0 ]&&{
echo "the first num is null"
exit 2
}
[ ${#b} -le 0 ]&&{
echo "the second num is null"
exit 3
}
expr $a + 1 &>/dev/null
RETVAL_A=$?
expr $b + 1 &>/dev/null
RETVAL_B=$?
if [ $RETVAL_A -ne 0 -o $RETVAL_B -ne 0 ];then
echo "one of the num is not num,pls input again..."
exit 4;
fi
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))"
[root@localhost shell]# sh calculate_read.sh
please input two number:a b
one of the num is not num,pls input again...
[root@localhost shell]# sh calculate_read.sh
please input two number:11 2
a-b=9
a+b=13
a*b=22
a/b=5
a**b=121
a%b=1
[root@localhost shell]# sh calculate_read.sh
please input two number:1
the second num is null
[root@localhost shell]# sh calculate_read.sh
please input two number: 1
the second num is null
[root@localhost shell]#