shell 编程 05 -- 变量的数值计算实践(readletexprbcdeclareawk杨辉三角)
Posted zhangfd
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell 编程 05 -- 变量的数值计算实践(readletexprbcdeclareawk杨辉三角)相关的知识,希望对你有一定的参考价值。
变量的数值计算实践
5.1 算术运算符
常见的算术运算符号
算术运算符 | 意义 |
---|---|
+ 、- | 加、减 |
*、/、% | 乘、除、取余(取模) |
** | 幂运算 |
++、-- | 自增、自减 |
!、&&、|| | 逻辑非、逻辑与、逻辑或 |
<、<=、>>= | 比较符号 |
==、!=、= | 比较符号 |
<<、>> | 向左移位、向右移位 |
~、| 、&、^ | 按位取反、按位异或、按位与、按位或 |
=、+=、-=、*=、/=、%= | 赋值运算符,a+=1等价于a=a+1 |
shell中常见的算术运算命令
运算操作符与运算命令 | 意义 |
---|---|
(()) | 整数运算 |
let | 整数运算,类似于(()) |
expr | 整数运算,有额外功能 |
bc | 适合整数和小数运算 |
$[] | 整数运算 |
awk | 适合整数和小数运算 |
declare | 定义变量值和属性,-i参数可用于定义整数变量做运算 |
5.2 双小括号"(())"整数数值运算命令
双小括号“(())”的作用是进行数值运算与数值比较,它的效率很高,用法灵活,是企业场景运维人员经常采用的运算操作符
双小括号“(())”的操作方法
运算操作符与运算命令 | 意义-- 只能做整数运算 |
---|---|
((i=i+1)) | 将i+1的结果赋值给i;echo $((i=i+1))输出结果 |
i=$((i+1)) | 在(())前加$符,表示将运算结果赋值给i |
((8>7&&5==5)) | 比较操作,可加入逻辑符号,用于条件判断 |
echo $((2+1)) | 在(())前加$,可直接输出运算表达式的运算结果 |
双小括号“(())”数值运算实践
## 数值运算
[root@zabbix ~]# a=8
[root@zabbix ~]# echo $((a=a+1))
9
[root@zabbix ~]# echo $((a+=1))
10
[root@zabbix ~]# echo $a
10
[root@zabbix ~]# echo $((a**2))
100
--------------------------------------
## 比较判断
[root@zabbix ~]# echo $((3<8)) --- 结果为真,输出1
1
[root@zabbix ~]# echo $((3>8)) --- 结果为假,输出0
0
[root@zabbix ~]# echo $((3==3)) --- 结果为真,输出1
1
[root@zabbix ~]# if ((8>7&&5==5)) --- 作为判断条件
> then
> echo yes
> fi
yes --- 输出结果
[root@zabbix ~]#
-------------------------------------------------------
## 自增自减
[root@zabbix ~]# a=10
[root@zabbix ~]# echo $((a++)) -- a++,表示先输出a的值10,a再自增1,a=11
10
[root@zabbix ~]# echo $a
11
[root@zabbix ~]# a=11
[root@zabbix ~]# echo $((a--)) -- a--,表示先输出a的值111,a再自减1,a=10
11
[root@zabbix ~]# echo $a
10
[root@zabbix ~]# a=10
[root@zabbix ~]# echo $((++a)) -- ++a,表示先输出a+1的值,a再自增1=11
11
[root@zabbix ~]# echo $a
11
[root@zabbix ~]# a=11
[root@zabbix ~]# echo $((--a)) -- --a,表示先输出a-1的值,a再自减1=10
10
[root@zabbix ~]# echo $a
10
--执行echo $((a++))和echo $((a--))命令输出整个表达式时,输出的值即为a的值,表达式执行完毕后,会对a进行++、--的运算,
--而执行echo $((++a))和echo $((--a))命令输出整个表达式时,会先对a进行++、--的运算,然后再输出表达式的值,即为a运算后的值。
5.2.3 read 方式实现简单计算器
read 方式实现简单计算器,等价于echo $((num1 * num2))
[root@zabbix 0506]# cat read.sh
#!/bin/bash
# add,sub,multi,divide caculate by moox.
print_usage(){
printf "Please enter an integer
"
exit 1
}
read -p "Please input first number:" firstnum
if [ -z $firstnum ] || [ -n "`echo $firstnum|sed ‘s/[0-9]//g‘`" ]
then
print_usage
fi
read -p "Please input the aperations:" operators
if [ "$operators" != "+" ] && [ "$operators" != "-" ]&& [ "$operators" != "*" ]&&[ "$operators" != "/" ]
then
echo "please input {+|-|*|/}"
exit 2
fi
read -p "Please input second number:" secondnum
if [ -z $secondnum ] || [ -n "`echo $secondnum|sed ‘s/[0-9]//g‘`" ]
then
print_usage
fi
echo "${firstnum}${operators}${secondnum}=$((${firstnum}${operators}${secondnum}))"
-------------------
## 等价用法
[root@zabbix 0506]# cat cacu.sh
echo $(($1))
[root@zabbix 0506]# sh cacu.sh "2 * 100"
200
5.3 let 运算命令的用法
let运算命令的语法格式为:let赋值表达式
let赋值表达式的功能等同于“((赋值表达式))”
5.3.1 用法:
[root@zabbix ~]# unset i
[root@zabbix ~]# i=2
[root@zabbix ~]# let i=i+8
[root@zabbix ~]# echo $i
10
5.3.2 let应用案例:监控Web服务状态
监控Web服务状态,如果访问两次均失败,则报警(let应用案例)
[root@zabbix 0506]# cat check_url.sh
#!/bin/bash
CheckUrl(){
timeout=5
fails=0
success=0
while true
do
wget --timeout=$timeout --tries=1 http://oldboy.blog.51cto.com -q -O /dev/null
if [ $? -ne 0 ]
then
let fails=fails+1
else
let success=success+1
fi
if [ $success -ge 1 ]
then
echo success
exit 0
fi
if [ $fails -le 2 ]
then
Critical="sys is down."
echo $Critical|tee|mail -s "$Critical" 2144865225@qq.com
exit 2
fi
done
}
CheckUrl
[root@zabbix 0506]# sh check_url.sh
success
5.4 expr命令的用法
expr(evaluate(求值)expressions(表达式))命令既可以用于整数运算,也可以用于相关字符串长度、匹配等的运算处理。
5.4.1 expr用于计算语法:expr Expression
[root@zabbix 0506]# expr 2+2
2+2
[root@zabbix 0506]# expr 2 + 2
4
[root@zabbix 0506]# expr 2 - 2
0
[root@zabbix 0506]# expr 2 * 2
expr: syntax error
[root@zabbix 0506]# expr 2 * 2
4
[root@zabbix 0506]# expr 2 / 2
1
## 要注意,在使用expr时:
运算符及用于计算的数字左右都至少有一个空格,否则会报错。
使用乘号时,必须用反斜线屏蔽其特定含义,因为Shell可能会误解星号的含义。
5.4.2 expr配合变量计算
expr在Shell中可配合变量进行计算,但需要用反引号将计算表达式括起来。
[root@zabbix 0506]# i=5
[root@zabbix 0506]# i=`expr $i + 6`
[root@zabbix 0506]# echo $i
11
5.4.3 expr 实例:判断变量值是否为整数
判断一个变量值或字符串是否为整数:利用以expr做计算时变量或字符串必须是整数的规则,把一个变量或字符串和一个已知的整数(非0)相加,看命令返回的值是否为0。如果为0,就认为做加法的变量或字符串为整数,否则就不是整数
- 通过expr判断变量或字符串是否为整数。
[root@zabbix 0506]# i=5
[root@zabbix 0506]# expr $i + 6
11 -- 可将结果> /dev/null,不做输出
[root@zabbix 0506]# echo $?
0 --- 结果为0
[root@zabbix 0506]# i=oldboy
[root@zabbix 0506]# expr $i + 6
expr: non-integer argument -- 可将结果> /dev/null,不做输出
[root@zabbix 0506]# echo $?
127 --- 结果非0
- 通过传参判断输出内容是否为整数
[root@zabbix 0506]# cat expr.sh
#!/bin/bash
expr $1 + 1 > /dev/null 2>&1
[ $? -eq 0 ] && echo int || echo chars
-----------------------------------------------
[root@zabbix 0506]# sh expr.sh 11
int
[root@zabbix 0506]# sh expr.sh aa
chars
- 通过read读入持续等待输入例子
[root@zabbix 0506]# cat read_expr.sh
#!/bin/bash
while true
do
read -p "Pls input :" a
expr $a + 1 >/dev/null 2>&1
[ $? -eq 0 ] && echo int ||echo chars
done
-------------------------------------------------
[root@zabbix 0506]# sh read_expr.sh
Pls input :ss
chars
Pls input :277
int
Pls input :^C
5.4.4 expr的特殊用法(扩展名判断)
- 通过expr判断文件扩展名是否符合要求
[root@zabbix 0506]# cat expr_end.sh
#!/bin/bash
if expr "$1" : ".*.pub" &>/dev/null
then
echo "you are using $1"
else
echo "please use *.pub file."
fi
----------------------------------------
[root@zabbix 0506]# sh expr_end.sh aa
please use *.pub file.
[root@zabbix 0506]# sh expr_end.sh aa.pub
you are using aa.pub
[root@zabbix 0506]#
- 使用expr命令实现系统ssh服务自带的ssh-copy-id公钥分发脚本。
[root@zabbix 0506]# cat ssh-copy-id.sh
#!/bin/bash
echo "$0 $1 $2 $3 "
if [ "-i" = "$1" ];then
shift
echo "$1 $2"
if [ -n "$2" ];then
if expr "$1" : ".*.pub" &>/dev/null;then
ID_FILE="$1"
else
ID_FILE="$1.pub"
fi
echo $ID_FILE
fi
fi
--------------------------------------------------------------------
[root@zabbix 0506]# sh ssh-copy-id.sh -i aa root@172.16.1.31:~/
ssh-copy-id.sh -i aa root@172.16.1.31:~/
aa root@172.16.1.31:~/
aa.pub
- expr 实现Shell脚本,打印下面语句中字符数不大于6的单词
I am oldboy linux,welcome to our training.
for n in `echo "I am oldboy linux,welcome to our training."|tr ",|." " "`
do
if [ `expr length "$n"` -le 6 ]
then
echo $n
fi
done
5.5 bc命令的用法
5.5.1 bc作为计算器来应用,直接bc命令
[root@zabbix 0506]# 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‘.
45-14*515-47+4
-7208
5.5.2 bc作为命令行来应用
[root@zabbix 0506]# echo 3+2|bc
5
[root@zabbix 0506]# echo 3+2.556|bc
5.556
[root@zabbix 0506]# echo "scale=3;3/2.556"|bc
1.173
[root@zabbix 0506]# echo "scale=7;3/2.556"|bc
1.1737089
5.5.3 bc计算输出1+2+…+10
# 通过一条命令计算输出1+2+3+…+10的表达式,并计算出结果,请使用bc命令计算。
# 输出内容如1+2+3+4+5+6+7+8+9+10=55
[root@zabbix 0506]# echo "`seq -s "+" 10`=`seq -s "+" 10|bc`"
1+2+3+4+5+6+7+8+9+10=55
5.6 awk 实现计算
利用awk进行运算的效果也很好,适合小数和整数,特别是命令行计算,尤其是小数,运算很精确,好用。来看个示例,如下:
[root@zabbix 0506]# echo "3 9"|awk ‘{print ($1-$2)/4}‘
-1.5
5.7 declare(同typeset)命令的用法
使用typeset定义整数变量,直接进行计算
[root@zabbix 0506]# declare -i A=30 B=7 ## declare -i参数可以将变量定义为整形
[root@zabbix 0506]# A=A+B ## 已声明是整形,可以直接计算
[root@zabbix 0506]# echo $A
37
5.8 $[] 符号的运算实例
5.8.1 打印数学杨辉三角
[root@zabbix 0506]# cat yanghsj.sh
#!/bin/bash
if (test -z $1) -- 判断传参的长度是否为0
then
read -p "Input Max Lines:" MAX -- 读入参数
else
MAX=$1 -- 已经传参,则赋值
fi
i=1 -- 初始行为1
while [ $i -le $MAX ] -- 行数控制
do
j=1 -- 初始列为1
while [ $j -le $i ] -- 列数控制,列数小于等于行数
do
f=$[i-1] -- 取位置:当前行的上一行
g=$[j-1] -- 取位置:当前列的前一列
if [ $j -eq $i ]||[ $j -eq 1 ] -- 控制首列值(j=1),尾列值(j=i)
then
declare SUM_${i}_$j=1 -- 控制每行的第一列和最后一列值都是1
else
declare A=$[SUM_${f}_$g] -- 取值:上一行前一列的值
declare B=$[SUM_${f}_$j] -- 取值:上一行当前列的值
## 取值:当前行当前列的值=上一行前一列的值+上一行当前列的值
declare SUM_${i}_$j=`expr $A + $B`
fi
echo -en $[SUM_${i}_${j}] -- 不换行输出每行每列的值
let j++ -- 列值+1
done
echo -- 取完每行的所有列值,输出换行
let i++ -- 行值+1
done
5.9 基于shell变量输入read命令的运算实践
语法格式:read [参数] [变量名]
常用参数如下。
-p prompt:设置提示信息。
-t timeout:设置输入等待的时间,单位默认为秒
- 功能演示:
# -t 参数指定等待时间,10秒后退出读取
# -p 参数指定提示信息
# 不使用参数时,直接跟变量
[root@zabbix 0506]# read -t 10 -p "please input a num:" num1
please input a num: 100
[root@zabbix 0506]# echo $num1
100
[root@zabbix 0506]# read aa bb
1001 1002
[root@zabbix 0506]# echo $aa ;echo $bb
1001
1002
- read -p 功能可用echo -n 实现
[root@zabbix 0506]# echo -n "please input a num:" && read num1
please input a num:100
[root@zabbix 0506]# echo $num1
100
以上是关于shell 编程 05 -- 变量的数值计算实践(readletexprbcdeclareawk杨辉三角)的主要内容,如果未能解决你的问题,请参考以下文章
《跟老男孩学Linux运维之shell编程实战》-第四章 变量的数值计算