写点什么

shell 运算详解,看这一篇就够了!

  • 2022 年 8 月 10 日
    四川
  • 本文字数:4745 字

    阅读完需:约 16 分钟

shell运算详解,看这一篇就够了!

计算机编程就是三大步:输入、运算、输出


那么计算机运算有哪些呢,计算机能做哪些运算呢?


我们来看看常见的计算机运算

一、赋值运算



赋值运算符 =


a=10      name='baism'  重点:字符串必须用引号引起来
复制代码

二、算术运算(四则运算)


2.1 运算符与命令

四则运算符:


+ → 加


- → 减


* → 乘


\ → 除


扩展: % → 取余


** → 开方


运算命令:


  • 整形运算– exprlet $(())bc

  • 浮点运算– bc

2.2 整形运算

expr 命令:


只能做整数运算,格式比较古板,注意空格


[root@liza ~]# expr 1 + 12[root@liza ~]# expr 5 - 23[root@liza ~]# expr 5 \* 2  #注意*出现应该转义,否则认为是通配符10[root@liza ~]# expr 5 / 22[root@liza ~]# expr 5 % 21
复制代码


let命令:


只能做整数运算,且运算元素必须是变量,无法直接对整数做运算


[root@liza ~]# let a=100+3;echo $a103root@liza ~]# let a=100-3;echo $a97[root@liza ~]# let a=100/3;echo $a33[root@liza ~]# let a=100*3;echo $a300[root@liza ~]# let a=100%3;echo $a1[root@liza ~]# let a=100**3;echo $a1000000[root@liza ~]# a=100[root@liza ~]# let a++;echo $a101[root@liza ~]# let a--;echo $a100[root@liza ~]# let a-=3;echo $a97[root@liza ~]# let a+=5;echo $a102
复制代码


双小圆括号运算,在 shell 中(( ))也可以用来做数学运算


[root@liza ~]# echo $(( 100+3))103[root@liza ~]# echo $(( 100-3)) 97[root@liza ~]# echo $(( 100%3))1[root@liza ~]# echo $(( 100*3))300[root@liza ~]# echo $(( 100/3))33[root@liza ~]# echo $(( 100**3))     #开方运算1000000
复制代码

2.3 浮点运算

浮点运算是采用的命令组合的方式来实现的 echo “scale=N;表达式”|bc


[root@liza ~]# echo "scale=2;3+100"|bc103[root@liza ~]# echo "scale=2;100-3"|bc97[root@liza ~]# echo "scale=2;100/3"|bc33.33[root@liza ~]# echo "scale=2;100*3"|bc300
复制代码

2.4 练习案例

2.4.1 实现一个四则运算计算器

案例思考: 计算器的功能: + - * \


实现步骤:


  1. 要求用户传输三个参数,num1 算术运算符 num2

  2. 运算输出结果


实现代码


#!/bin/bash# #Author: li za#Release: #Description: 简单计算器
echo "$1 $2 $3"|bc
复制代码
2.4.2 内存使用率统计,要求打印内存使用率

案例思考:


  1. 内存总量 获得方式是什么 free top /proc/meminfo

  2. 内存使用量

  3. 内存使用率公式 使用量/总量*100%


实现步骤:


  1. 获取内存总量

  2. 获取内存使用量

  3. 运算输出结果


实现代码


#!/bin/bash# #Author: li za#Release: #Description:内存使用率计算脚本
#free#1、获得内存总量memory_total=`free -m|grep -i "mem"|tr -s " "|cut -d " " -f2`
#2、获得内存使用的量memory_use=`free -m|grep -i "mem"|tr -s " "|cut -d " " -f3`
#3、计算输出#运算的时候是否需要小数点 浮点运算,要考虑使用的命令 (难点 重点)#echo "内存使用率: $((memory_use*100/memory_total))%"#难点:浮点运算中,同优先级的情况下,大数除以小数 尽可能保证精确echo "内存使用率: `echo "scale=2;$memory_use*100/$memory_total"|bc`%"
复制代码

三、比较运算



计算机除了算术赋值运算外,还有比较运算


比如说比较两个数的关系,比较两个字符串的关系【用户登录系统】等

3.1 整形比较运算

            运算符解释:
精确比较: -eq 等于 equal
-gt 大于
-lt 小于
模糊比较: -ge 大于或等于
-le 小于或等于
-ne 不等于
复制代码


通过 test 命令比较两个整数关系


[root@liza ~]# test 100 -gt 300;echo $?1[root@liza ~]# test 100 -ge 300;echo $?1[root@liza ~]# test 100 -eq 300;echo $?1[root@liza ~]# test 100 -le 300;echo $?0[root@liza ~]# test 100 -lt 300;echo $?0[root@liza ~]# test 100 -ne 300;echo $?0
备注:linux命令test只能比较两个整数的关系,不会返回结果,需要通过$?才能看到结果
复制代码

3.2 练习案例

3.2.1 写一个脚本实现对两个证书关系的判断

案例思考:


两个数有几种关系?


  1. 大于

  2. 小于

  3. 等于


实现步骤


  1. 交互或者外传参的方式获得两个整数

  2. 判断关系

  3. 输出结果实现代码


#!/bin/bash# #Author: li za##Release: #Description:判断两个数的关系
#1、输入两个数,$1 $2
#2、判断两个数关系if [ $1 -gt $2 ];then #3、输出结果 echo "$1 > $2 "elif [ $1 -eq $2 ];then echo "$1 = $2"else echo "$1 < $2"fi
复制代码
3.2.2 判断两个浮点数的关系

案例思考 shell 中的浮点类型如何做比较运算?


默认情况下 shell 是不能判断浮点的,那么在 linux 中又避免不了需要进行浮点运算,那怎么解决


解决思路如下:


  1. 两个数据同时放大到整数倍

  2. 处理掉小数点位,保留整数位

  3. 进行整形判断


实现代码
#!/bin/bash# #Author: li za##Release: #Description:判断两位小数点的关系
#1、交互或者外传参的方式获得两个整数#$1 $2[ $# -lt 2 ]&&echo "need two args"&&exit 1
#采用外传参的方式接收数据并放大100倍,并处理为整数num1=`echo "scale=2;$1*100"|bc|cut -d "." -f1`num2=`echo "scale=2;$2*100"|bc|cut -d "." -f1`
#2、比较运算if [ $num1 -gt $num2 ];then #3、输出结果 echo "$1 > $2"elif [ $num1 -lt $num2 ];then echo "$1 < $2"else echo "$1 = $2"fi
复制代码

3.3、字符串比较运算

3.3.1 字符串比较运算符

运算符解释,注意字符串一定别忘了使用引号引起来


  ==          等于     !=          不等于  -n          检查字符串的长度是否大于0    -z          检查字符串的长度是否为0
复制代码
3.3.2 比较两个字符串关系
[root@liza ~]# test 'root' == 'root';echo $?0[root@liza ~]# test 'root' != 'root1';echo $?0[root@liza ~]# name=[root@liza ~]# test -n "$name";echo $?1[root@liza ~]# test -z "$name";echo $?0
复制代码
3.3.3 练习案例

案例需求:


模拟一个 linux 文本界面登陆程序,要求账号密码验证成功进入系统,账号密码验证失败退回登陆界面


案例思考:


  1. 熟悉 linux 文本界面登陆步骤

  2. 熟悉字符串比较运算


案例步骤:


  1. 预设正确账号、密码

  2. 输出提示登录信息并实现交互登录

  3. 输出密码输入信息并实现交互

  4. 判断输入是否正确

  5. 1.正确,进入系统

  6. 2.不正确 继续运行该脚本


实现代码


#!/bin/bash# #Author: li za#Created Time: #Release: #Description: 仿真登陆####default_account='root'default_pw='123456'

######main#1、清屏clear#2、输出提示信息echo "CentOS Linux 8 (Core)"echo -e "Kernel `uname -r` on an `uname -m`\n"
#3、交互输入登陆名echo -n "$HOSTNAME login: "read account
#4、交互输入密码read -s -t30 -p "Password: " pw
#5、判断用户输入是否正确if [ "$default_account" == "$account" ] && [ "$default_pw" == "$pw" ];then clear echo -e "\nwelcome to root"else echo "用户名或密码错误..." #输入错误,再次调用本脚本 sh $0fi
复制代码

四、逻辑运算



完成一个任务中需要多个条件都满足或者多个条件中只要满足一个即可,那么这就是我们的逻辑运算。


通过多个条件判断结果,才能得出结论

4.1 逻辑运算应用场景

多条件同时判断
复制代码

4.2 逻辑运算符

​ 逻辑与运算     &&
​ 逻辑或运算 ||
​ 逻辑非运算 !
复制代码


逻辑运算秘籍


逻辑运算注意事项:        逻辑与、或运算都需要两个或以上条件        逻辑非运算只能一个条件          口诀:    逻辑与运算               真真为真 真假为假   假假为假          逻辑或运算               真真为真 真假为真   假假为假          逻辑非运算               非假为真   非真为假                          逻辑与或的短路运算
逻辑与中靠前的条件中出现了假,后面的就不在判断了,因为已经是假的了
逻辑或中靠前的条件中出现了真,后不在往后判断了,结果已经为真了
复制代码

4.3 练习案例

明白了逻辑运算符和逻辑运算的口诀和短路运算后,看一个案例


上一个字符串运算练习案例(3.3.3)中练习的是仿真用户登录,判断登陆的方式是分步判断的,既先判断用户名,不管是否正确都会继续判断密码的正确性,这样是两步判断


既然已知用户名是错误的啦,完全没必要在判断密码的正确性了,因为结果都一样,你不能进入系统


既然判断一个用户输入的用户名和密码是否正确,且一个不正确就不能进入系统,那么我们可以这么去思考一下:两个条件全为真则进入系统,两个条件一个为假则重新登陆


这样是不是就满足了逻辑与运算了,同时思考逻辑与运算的短路运算,逻辑与条件中的判断顺序是从前往后,前边一个条件为假的时候,后边的条件就不用判断了,那么就减少了判断的次数,加快了运算速度

4.3.1 升级版的仿真用户登录系统

案例需求


使用逻辑运算写一个仿真用户登录验证程序


案例思路


  1. 输入用户名

  2. 输入密码

  3. 与运算返回结果


案例代码
#!/bin/bashecho "CentOS linux 8 (Core)"echo -e "Kernel `uname -r` on an `uname -m` \n"
#1、输入用户名echo -n "$HOSTNAME login: "read myuser
#echo -n "password: "#read -s -t 5 -n 2 pw
#2、输入密码read -p "password: " -s -t 5 -n 6 pw
#3、与运算返回结果[ $myuser == 'root' ] && [ $pw == '123456' ] && echo yes || echo no
复制代码

五、文件判断(文件类型、权限、新旧判断)



linux 的设计思路:一切皆文件,对文件系统的操作其实可以狭隘的理解为对文件的操作


如果希望对文件类型和权限或者两个文件做新旧或者是否同一个文件进行判断

5.1、test 判断命令

命令功能: 检测文件类型和比较运算


命令用法


    test [命令选项] 表达式
复制代码


命令选项
-d 检查文件是否存在且为目录-e 检查文件是否存在-f 检查文件是否存在且为文件-r 检查文件是否存在且可读-s 检查文件是否存在且不为空-w 检查文件是否存在且可写-x 检查文件是否存在且可执行-O 检查文件是否存在并且被当前用户拥有-G 检查文件是否存在并且默认组为当前用户组-nt file1 -nt file2 检查file1是否比file2新-ot file1 -ot file2 检查file1是否比file2旧 -ef file1 -ef file2 检查file1是否与file2是同一个文件,判定依据的是i节点
以上只列出部分命令选项,详细的可以通过:man test获得。
复制代码


命令用法练习:


文件类型


[root@liza ~]# test -f /etc/passwd;echo $?0[root@liza ~]# test -f /etc;echo $?1[root@liza ~]# test -d /etc;echo $?0
复制代码


权限判断


[root@liza ~]# test -x /root/anaconda-ks.cfg ;echo $?1[root@liza ~]# ll /root/anaconda-ks.cfg -rw-------. 1 root root 1216 6月  26 09:06 /root/anaconda-ks.cfg[root@liza ~]# test -r /root/anaconda-ks.cfg ;echo $?0
[root@liza ~]# test -w /root/anaconda-ks.cfg ;echo $?0
复制代码

5.2 练习案例

案例需求


写一个平滑关闭服务脚本


案例思路


  1. 判断服务进程文件是否存在,存在读取 PID 并判断是否存在进程

  2. 进程存在就使用 Kill 命令结束服务

  3. 不存在就报“服务已经结束“


案例步骤


  1. 检查服务 PID 文件

  2. 检查进程是否存在

  3. 杀死进程


案例代码


#!/bin/bash# #Author: li za##Release: #Description:找到服务的PID号,如果服务开启则杀死,否则提示服务已经关闭或不存在
#1、判断PID#注意PID的路径,如果服务的PID不在这里可以做个软连接if [ -f /var/run/$1.pid ];then #2、如果存在 PID=`cat /var/run/$1.pid` #3、统计进程数 process_num=`ps aux|grep $PID|wc -l` #5、判断进程数大于2则杀死 if [ $process_num -ge 2 ];then kill -s QUIT $PID else #5、判断小于2则提示进程不存在,同时删除服务PID文件 echo "service $1 is close" rm -f /var/run/$1.pid fielse #2、不存在 echo "service $1 is close"fi
复制代码


发布于: 刚刚阅读数: 3
用户头像

🏅️ InfoQ 专家博主 2022.03.08 加入

CSDN:飞向星的客机

评论

发布
暂无评论
shell运算详解,看这一篇就够了!_Linux_飞向星的客机_InfoQ写作社区