[转帖]shell编程:变量的数值计算实践(五)
https://www.cnblogs.com/luoahong/articles/9224495.html
算术运算符

变量的数值(整数)计算
1)(())用法:(此方法很常用)**

范例:shell的算术运算实例如下:
|
1
2
3
4
5
6
7
8
|
[root@db01 ~]# ((a=1+2**3-4%3))[root@db01 ~]# echo $a8[root@db01 ~]# ((a=1+2**3-4%3))[root@db01 ~]# echo $a8[root@db01 ~]# echo $((1+2**3-4%3))8 |
记忆方法:++,--
变量a在前,表达式的值为a,然后a自增或自减,变量a在符号后,表达式值自增或自减,然后a值自增或自减
|
1
2
3
|
[root@db01 ~]# a=$((100*(100+1)/2))[root@db01 ~]# echo $a5050 |
范例6:这是一个实践考试题,内容如下:
把a,b两个变量通过命令行脚本传参的方式实现上面混合运算脚本的功能
第一种方法:
|
1
2
3
4
5
6
7
8
9
|
#!/bin/basha=6b=2echo "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 ))" |
第二种方法:
|
1
2
3
4
5
6
7
8
9
10
|
[root@web02 ~]# cat abc.sh#!/bin/basha=$1b=$2echo "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 ))" |
2)let命令的用法(整数)
格式: let 赋值表达式
【注】let赋值表达式功能等同于:((赋值表达式))
范例1:给自变量i加8
|
1
2
3
4
|
[root@db01 scripts]# i=2[root@db01 scripts]# let i=i+8[root@db01 scripts]# echo $i10 |
范例2:监控web服务状态,如果访问两次均失败,则报警(let应用案例)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
[root@adminset 05]# cat checkurl.sh#!/bin/bashCheckUrl() {timeout=5fails=0success=0while true do wget --timeout=$timeout --tries=1 http://www.baidu.com -q -o /dev/null if [ $? -ne 0 ] then let fails=fails+1 else let success+=1 fi if [ $success -ge 1 ] then echo sunccess exit 0 fi if [ $fails -ge 2 ] then Critical="sys is down" echo $Critical|tee|mail -s "$Critical" 249495480@qq.com exit 2 fidone}CheckUrl |
运行结果:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
[root@adminset 05]# sh checkurl.shsunccess[root@adminset 05]# sh +x checkurl.shsunccess[root@adminset 05]# sh -x checkurl.sh+ CheckUrl+ timeout=5+ fails=0+ success=0+ true+ wget --timeout=5 --tries=1 http://www.baidu.com -q -o /dev/null+ '[' 0 -ne 0 ']'+ let success+=1+ '[' 1 -ge 1 ']'+ echo sunccesssunccess+ exit 0 |
3)expr (evaluate(求值)expressions(表达式))命令的用法:
expr命令一般用于整数值,但也可用于字符串,用来求表达式变量的值,同时expr也是一个手工命令计算器
范例:命令运算用法实践
|
1
2
3
4
5
6
7
8
9
10
11
12
|
[root@adminset 05]# expr 2+22+2[root@adminset 05]# expr 2 + 24[root@adminset 05]# expr 2 - 20[root@adminset 05]# expr 2 * 2expr: syntax error[root@adminset 05]# expr 2 \* 24[root@adminset 05]# expr 2 / 21 |
要注意,在使用expr时:
- 运算符及用于计算的数字左右都至少有一个空格,否则会报错
- 使用称号时:必须用反斜线屏蔽其特定含义,因为Shell可能会误解星号的含义
范例:给自变量i加6
|
1
2
3
4
5
|
[root@adminset 05]# i=5[root@adminset 05]# i=`expr $i + 6`#注意用反引号将表达式引起来,变量和数字符号两边有空格[root@adminset 05]# echo $i11 |
范例:通过传参判断输出内容是否为整数
|
1
2
3
4
|
#!/bin/shexpr $1 + 1>/dev/null 2>&1[ $? -eq 0 ]&&echo int||echo chars#这是一个条件表达式语法,返回值为0,则输出int,否则输出chars |
范例:通过read读入持续等待输入例子(此为范例5-16的加强版)
|
1
2
3
4
5
6
7
|
#!/bin/shwhile truedo read -p "pls input:" a expr $a + 0 >/dev/null 2>&1 [ $? -eq 0 ] && ehco int || echo charsdone |
四种运算方法:
1.(())
2.let
3.expr
4.[]
整数
判断一个文件的扩展名是不是pub(发送公钥的命令就是使用此参数)
|
1
2
3
4
5
6
7
8
9
10
11
|
#!/bin/shif expr "$1" : ".*\.pub" &>/dev/nullthenecho "you are using $1"elseecho "pls use *.pub file"fi[root@web02 ~]# sh aaa.sh oldboypls use *.pub file[root@web02 ~]# sh aaa.sh oldboy.pubyou are using oldboy.pub |
判断一个输入是不是数字
|
1
2
3
4
5
6
7
|
#!/bin/shwhile truedoread -p "Pls input:" aexpr $a + 0 >/dev/null 2>&1[ $? -eq 0 ] &&echo int||echo charsdone |
如果判断是不是数字,就执行错误shars
|
1
2
3
4
5
6
7
8
9
10
11
12
|
[root@db01 scripts]# cat b.sh#!/bin/shexpr $1 + 1 >/dev/null 2>&1[ $? -eq 0 ] &&echo int||echo chars[root@db01 scripts]# sh b.sh 1int[root@db01 scripts]# sh b.sh 1achars[root@db01 scripts]# sh b.sh 100int[root@db01 scripts]# sh b.sh 100abcchars |
expr match 整数判断
|
1
2
3
4
|
[[ `expr match "$a" "[0-9][0-9]*$"` == 0 ]] && {echo "the first is not a num"exit 3} |
计算变量长度
|
1
2
3
|
[root@db01 scripts]# a="oldboy"[root@db01 scripts]# expr length "$a"6 |
expr功能
1.整数计算
2.判断扩展名
3.判断输入是否为整数
4.计算变量的长度
bc命令用法
|
1
2
3
4
5
6
7
8
9
10
11
|
[root@db01 scripts]# bcbc 1.06.95Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.This is free software with ABSOLUTELY NO WARRANTY.For details type `warranty'.1+121+346*848 |
另一种使用bc的方式
|
1
2
3
4
|
[root@db01 scripts]# echo 1+2|bc3[root@db01 scripts]# echo 8-2|bc6 |
inux下的bc命令可以设置结果的位数,通过scale.
|
1
2
3
4
5
6
7
|
[root@db01 scripts]# echo "scale=3;5.23 / 3.13"|bc1.670[root@db01 scripts]# echo "scale=2;5.23 / 3.13"|bc1.67比如:$ echo "scale=4; 1.2323293128 / 1.1" | bc -l1.1202 |
bc命令简单的计算
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
[root@web02 ~]# i=2[root@web02 ~]# i=`echo $i+1|bc`[root@web02 ~]# echo $i3可以做加法计算[root@web02 ~]# echo 3.5+53.5+5[root@web02 ~]# echo 3.5+5|bc8.5减法计算[root@web02 ~]# echo 3.5-5|bc-1.5乘法计算[root@web02 ~]# echo 3.5*5|bc17.5保留位数(bc的用处不大)[root@web02 ~]# echo "scale=2; 3.5*5.1"|bc17.85[root@web02 ~]# echo "scale=2; 3*5"|bc15[root@web02 ~]# echo "scale=1; 3*5"|bc15提示:bc是特有的小数计算awk也可以进行小数计算[root@web02 ~]# echo "5.5 5.6" |awk '{print ($2-$1)}'0.1[root@web02 ~]# echo "5.5 5.5" |awk '{print ($2+$1)}'11 |
利用bc配合变量运算
|
1
2
3
4
|
[root@adminset 05]# i=5[root@adminset 05]# i=`echo $i+6|bc` #利用echo输出表达式,通过管道交给bc计算,此方法效率较低[root@adminset 05]# echo $i11 |
提示:根据bc所具有的特殊性来看:
- 如果小数,则选择bc运算没有问题(老男孩推荐awk)
- 若是整数场景,可用(())、let、expr等
范例:通过一条命令计算输出1+2+3+...+10的表达式,并计算出结果,使用bc计算
输出内容如:1+2+3+4+5+6+7+8+9+10=55
第一种方法:
|
1
2
3
4
|
[root@web02 ~]# seq -s "+" " "101+2+3+4+5+6+7+8+9+10[root@web02 ~]# echo `seq -s "+" " "10`=`seq -s "+" " "10|bc`1+2+3+4+5+6+7+8+9+10=55 |
第二种方法:
|
1
2
3
4
|
[root@web02 ~]# echo {1..10}|tr " " "+"1+2+3+4+5+6+7+8+9+10[root@web02 ~]# echo `echo {1..10}|tr " " "+"`=`echo {1..10}|tr " " "+"|bc`1+2+3+4+5+6+7+8+9+10=55 |
更多方法:因计算不是重点,所以我们不重点研究。
|
1
2
3
4
5
6
7
8
9
10
11
12
|
[root@adminset 05]# echo `seq -s "+" 10`="$((`seq -s "+" 10`))"1+2+3+4+5+6+7+8+9+10=55#使用(())计算[root@adminset 05]# echo `seq -s "+" 10`=`seq -s "+" 10|bc`1+2+3+4+5+6+7+8+9+10=55#使用bc计算[root@adminset 05]# echo `seq -s "+" 10`=`seq -s " + " 10|xargs expr`1+2+3+4+5+6+7+8+9+10=55#使用expr计算[root@adminset 05]# echo `seq -s "+" 10`=$(echo $[`seq -s " + " 10`])1+2+3+4+5+6+7+8+9+10=55#使用$[]计算 |
特点:bc的独有特点是支持小数运算,当然也可以整数运算。
AWK实现计算
利用awk进行运算的效果也很好,适合小数和证书,特别是命令行计算,尤其是小数,运算很精确,好用
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
[root@adminset 05]# echo "7.7 3.8"|awk '{print ($1-3)/$2}'1.23684#$1为第一个数字,$1为第二个数字,用空格隔开,下同[root@adminset 05]# echo "7.7 3.8"|awk '{print ($1-$2)/$2}'1.02632[root@adminset 05]# echo "7.7 3.8"|awk '{print ($1-$2)}'3.9[root@adminset 05]# echo "358 113"|awk '{print ($1-3)/$2}'3.14159[root@adminset 05]# echo "3 9"|awk '{print ($1-3)*$2}'0[root@adminset 05]# echo "3 9"|awk '{print ($1+3)*$2}'54 |
declare(同typeset)命令的用法
下面将要讲解的是使用typeset定义整数变量,直接进行计算,这个方法不是很常用,因为需要定义才能生效,示例如下:
|
1
2
3
4
5
6
7
8
|
[root@adminset 05]#[root@adminset 05]# declare -i A=30 B=7 #declare -i参数可以将变量定义为整形[root@adminset 05]# A=A=B #因为已声明是整型,因此可以直接进行运算了[root@adminset 05]# echo $A7[root@adminset 05]# A=A+B[root@adminset 05]# echo $A14 |
$[]符号的运算示例
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
[root@adminset 05]#[root@adminset 05]# i=5[root@adminset 05]# i=$[i+6][root@adminset 05]# echo $i11[root@adminset 05]# echo $[2*3]6[root@adminset 05]# echo $[2**3]8[root@adminset 05]# echo $[2/5]0[root@adminset 05]# echo $[3/2]1[root@adminset 05]# echo $[3%2]1[root@adminset 05]# echo $[3 % 2]1 |
下面是一个解决实际问题的示例:打印数学杨辉三角
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
#!/bin/bashif (test -z $1);then #判断传参的值长度是不是为0,如果没有传入参数,则使用read读入 read -p "input MAX lines:" MAX #read读入一个数值else MAX=$1 #如果已经传参了,就把传参的$1赋值给MAXfi#上述脚本很巧妙地通过判断,实现了用户既可以传参输入,也可以read读入数字i=1 #i行控制while [ $i -le $,MAX ]do j=1 while [ $j -le $i ] #j行控制 do f=$[i-1] #f=i-1是$[]计算的写法 g=$[j-1] #g=j-1是$[]计算的写法 if [ $j -eq $i ] || [ $j -eq 1 ];then declare SUM_${i}_$j=1 #声明变量头尾都是1 else declare A=$[SUM_${f}_$j] #取上一行的j列变量 declare B=$[SUM_${f}_$g] #取上一行的j-1列变量 declare SUM_${i}_$j=`expr $A + $B` #声明并计算当前变量的值 fi echo -en $[SUM_${f}_$j]] " " #输出当前变量 let j++ #let运算用法 done #换行 echo #let运算用法 let i++done |
基于Shell变量输入read命令的运算实践
read命令基础
Shell变量除了可以直接复制或脚本传参外,还可以使用read命令从标准输入中获得,read为bash内置命令,可通过hlep read查看帮助

read的读入功能就相当于交互式接受用户输入,然后给变量赋值
范例:把前面加减乘除计算传参的脚本改成read方式读入整数变量
|
1
2
3
4
5
6
7
8
9
10
|
[root@adminset 05]# cat test1.sh#!/bin/bashread -t 15 -p "please input two number:" a becho "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))" |
执行结果如下:
|
1
2
3
4
5
6
7
8
|
[root@adminset 05]# sh test1.shplease input two number:10 5a-b=5a+b=15a*b=50a/b=2a**b=100000a%b=0 |
范例:以read命令读入及传参的综合企业案例

|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
[root@adminset 05]# cat test2.sh#!/bin/bash#no1read -t 15 -p "please input two number:" a b[ ${#a} -le 0 ] && { #利用条件表达式,根据变量值的长度是否小于0,来确定第一个数是否为空 echo "the first num is null" exit 1}[ ${#b} -le 0 ] && { #利用条件表达式,根据变量值的长度是否小于0,来确定第二个数是否为空 echo "the second num is null" exit 1}#no2expr $a + 1 &>/dev/nullRETVAL_A=$?expr $b + 1 &>/dev/nullRETVAL_B=$?if [ $RETVAL_A -ne 0 -o $RETVAL_B -ne 0 ];then echo "one of the num is not num,pls input again." exit 1fi#no3echo "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))" |
执行结果:
|
1
2
3
4
5
6
7
8
|
[root@adminset 05]# sh test2.shplease input two number:5 6a-b=-1a+b=11a*b=30a/b=0a**b=15625a%b=5 |
再来思考一下:如何将上述read读入改用脚本传参的方法来实现呢?
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
[root@adminset 05]# cat read1.sh#!/bin/basha=$1b=$2Usage(){ echo $"USAGE:sh $0 num1 num2" exit 1}if [ $# -ne 2 ];then Usagefiexpr $a + 1 >/dev/null 2>&1[ $? -ne 0 ] && Usageexpr $b + 0 >/dev/null 2>&1 #这个地方使用的加0,是为了防止b为0而导致除数为0[ $? -ne 0 ] && Usage#no3echo "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))"if [ $b -eq 0 ] #这个地方b做了个判断,防止被除数为0,算是个保险吧,可能用不上 then echo "your input does not allow to run." echo "a/b =error" echo "a%b =error"else echo "a/b =$(($a/$b))" echo "%b =$(($a%$b))"fi |
执行结果:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
[root@adminset 05]# sh read1.sh 3 7a-b=-4a+b=10a*b=21a/b=0a**b=2187a%b=3a/b =0a%b =3[root@adminset 05]# sh read1.shUSAGE:sh read1.sh num1 num2[root@adminset 05]# sh read1.sh 1 luoahongUSAGE:sh read1.sh num1 num2[root@adminset 05]# sh read1.sh 8 0a-b=8a+b=8a*b=0read1.sh: line 19: 8/0: division by 0 (error token is "0") |
[转帖]shell编程:变量的数值计算实践(五)的更多相关文章
- SHELL (4) —— 变量的数值计算实践
摘自:Oldboy Linux运维——SHELL编程实战 利用(())双括号进行比较及判断: [root@yeebian ~]# echo $((3<8)) 1 #1表示真. [root@yee ...
- shell编程——变量的数值计算
在shell脚本中,有时候会需要对数值类型的变量进行计算,通常我们用的是(()) [root@localhost collect]# ((a=1+2)) [root@localhost collect ...
- shell编程变量赋值
[shell编程变量赋值] 1.等号两边均不能有空格存在.例, a="hello world" 2.变量和其它文字以{}或空格格开,否则会混淆.例, 有时候变量名可能会和其它文 ...
- 在shell中变量的赋值有五种方法!
转至:https://blog.csdn.net/weibo1230123/article/details/82085226 在shell中变量的赋值有五种 :使用 read 命令,直接赋值,使用命令 ...
- Linux_10------Linux之shell编程------变量
.-9 vim num.sh #! /bin/bash num1=$1 num2=$2 sum=$(($num1+$num2)) #变量sum是num1和num2的综合 echo $sum 执行 ./ ...
- Linux Shell编程变量赋值和引用
我们可以使用任意一种文字编辑器,比如gedit.kedit.emacs.vi等来编写shell脚本,它必须以如下行开始(必须放在文件的第一行): #!/bin/sh ... 注意:最好使用“! ...
- shell编程—变量(三)
在shell脚本中,变量分两种,系统变量和自定义变量. 系统默认变量是系统自带的一些变量,如path为路径变量 用户自定义变量为在编写吧脚本的时候自己定义的一些变量 变量名命名规则 首个字符必须为字母 ...
- shell 编程 变量
转自:http://blog.csdn.net/qq504196282/article/details/52994249 shell之变量和引用 分类:SHELL编程基础 (470) (0) 举报 ...
- shell编程-变量
Shell支持自定义变量. 定义变量 定义变量时,变量名不加美元符号($),如: VALUE=“tmp” 注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样.同时,变量名的命名须遵 ...
- shell基础--变量的数值计算
变量的数值计算 1.$((表达式)) (1).实验1 [root@~_~ day4]# cat test.sh #!/bin/bash a=6 b=2 echo "a-b=$(($a-$b) ...
随机推荐
- Windows Server2016 默认使用英文输入法或默认使用中文输入法
1.确认是Server2016操作系统及以后版本 2.打开开始菜单"设置"--"时间和语言" 3.添加英文输入法(已存在可以跳过) 找到"区域与语言& ...
- Linux-LVM 磁盘扩容
LVM技术详解:视频1.视频2.视频3 安装lvm2后才支持如下命令 yum install -y lvm2 序号 功能 PV物理卷命令 VG卷组命令 LV逻辑卷命令 01 扫描功能 pvscan v ...
- OpenSSL命令总结
OpenSSL命令总结 疑今者察之古,不知来者视之往. 导航 介绍 对称加密 公钥加密 信息摘要 数字证书 杂项 介绍 密码学标准和互联网协议一样,是一种大家都遵守的约定和标准,比如PKCS#1中规定 ...
- [LitCTF 2023]1zjs
打开环境: 一个魔方♂ 习惯性打开 F12,之后发现有个./dist/index.umd.js Ctrl u 打开 把这个蓝色的点开 0.o? 这里眼神好的话就能看到有个" /f@k3f1a ...
- 一个小巧、快速、轻量级的 .NET NoSQL 嵌入式数据库
前言 今天给大家分享一个小巧.快速.轻量级的 .NET NoSQL 嵌入式数据库:LiteDB.本篇文章主要是介绍LiteDB和在.NET中如何使用. LiteDB介绍 LiteDB 是一个小巧.快速 ...
- PyTorch项目源码学习(2)——Tensor代码结构初步学习
PyTorch版本:1.10.0 Tensor Tensor是Pytorch项目较为重要的一部分,其中的主要功能如存储,运算由C++和CUDA实现,本文主要从前端开始探索学习Tensor的代码结构. ...
- Java 查找并替换PDF中的指定文本
本文介绍通过Java程序批量替换PDF中的指定文本内容. 1. 程序环境准备如下: 程序使用环境如图,需要注意的是,本文使用了免费版的PDF jar工具:另外JDK版本建议使用高版本更佳. jar ...
- 7种创建方式,带你理解Java的单例模式
本文分享自华为云社区<<Java极简设计模式>第01章:单例模式(Singleton)>,作者:冰 河. 单例设计模式 看几个单例对象的示例代码,其中有些代码是线程安全的,有些 ...
- PPT 动画-旋转唱片
插入图片.同心圆 按Shift 先点击背景图片,再点击 同心圆 合并形状,选择相交 设置动画,选择 陀螺旋,持续时间为 8秒, 打开计时窗口,重复为:直到幻灯片末尾
- Python中节省内存的方法之一:__slots__属性
Python是一门动态语言,可以在运行过程中,修改实例的属性和增删方法.任何实例都包含一个字典__dict__,该字典保存了实例所有的属性和方法.Python也通过这个字典可以将任意属性绑定到实例上. ...