当前位置: 首页 > backend >正文

day029-Shell自动化编程-计算与while循环

文章目录

  • 1. read 交互式初始化变量
    • 1.1 案例-安装不同的软件
    • 1.2 案例-比较大小
  • 2. 计算
    • 2.1 bc
    • 2.2 awk
    • 2.3 expr
    • 2.4 let
    • 2.5 案例-计算内存的空闲率
    • 2.6 案例-检查域名过期时间和https整数过期时间
  • 3. 循环
    • 3.1 循环控制语句
    • 3.2 for循环-c语言格式
    • 3.3 while循环
      • 3.3.1 案例-猜数字
      • 3.3.2 读取文件
      • 3.3.3 案例-读取文件,批量ping和wget
  • 4. 踩坑记录
    • 1. -bash: 条件表达式中有语法错误
  • 5. 思维导图

1. read 交互式初始化变量

  • read是从标准输入获取数据,一般用来在脚本中交互式为变量赋值
  • -p “信息”:打印提示信息
  • -t:设置输入时间
  • -s:静默模式,不显示输入的数据,类似于输入密码

1.1 案例-安装不同的软件

[root@oldboy99-Kylin /server/scripts]# cat read_install_pkg.sh
#!/bin/bash
##############################################################
# File Name: read_install_pkg.sh
# Version: V1.0
# Author: SunKexu
# Organization: www.oldboyedu.com
# Description:
##############################################################export LANG=en_US.UTF-8
cat <<EOF
请选择:
1.安装nginx
2.安装php
3.安装mysql
4.安装DeepSeek
5.安装tomcat
6.安装所有
7.退出
EOF
# read
read -p "请输入您的选择:" choose# vars# command
case $choose in1)echo install nginx ;;2)echo install php ;;3)echo install mysql ;;4)echo install DeepSeek ;;5)echo install tomcat ;;6)echo install all ;;7) exit ;;*)echo "Usage:$0 数字"exit 1
esac[root@oldboy99-Kylin /server/scripts]# bash read_install_pkg.sh
请选择:
1.安装nginx
2.安装php
3.安装mysql
4.安装DeepSeek
5.安装tomcat
6.安装所有
7.退出
请输入您的选择:100
Usage:read_install_pkg.sh 数字
[root@oldboy99-Kylin /server/scripts]# bash read_install_pkg.sh
请选择:
1.安装nginx
2.安装php
3.安装mysql
4.安装DeepSeek
5.安装tomcat
6.安装所有
7.退出
请输入您的选择:1
install nginx
[root@oldboy99-Kylin /server/scripts]# bash read_install_pkg.sh
请选择:
1.安装nginx
2.安装php
3.安装mysql
4.安装DeepSeek
5.安装tomcat
6.安装所有
7.退出
请输入您的选择:6
install all
[root@oldboy99-Kylin /server/scripts]# bash read_install_pkg.sh
请选择:
1.安装nginx
2.安装php
3.安装mysql
4.安装DeepSeek
5.安装tomcat
6.安装所有
7.退出
请输入您的选择:7

1.2 案例-比较大小

[root@oldboy99-Kylin /server/scripts]# cat compare_2.sh
#!/bin/bash
##############################################################
# File Name: compare_2.sh
# Version: V1.0
# Author: SunKexu
# Organization: www.oldboyedu.com
# Description:比较大小,交互传参
##############################################################
export LANG=en_US.UTF-8# vars
read -p "请输入参数1、参数2:" num1 num2# command
# 判断是否是数字
if [[ ! "$num1" =~ ^-?[0-9]+$ || ! "$num2" =~ ^-?[0-9]+$ ]];thenecho "$num1或者${num2}不是数字"exit 1
fi
#[[ "$num2" =~ ^-?[0-9]+$ ]] || {
#	echo "$num2 不是数字"
#	exit 1
#}
# 比较
if [ $num1 -gt $num2 ];thenecho "$num1 > $num2"
elif [ $num1 -eq $num2 ];thenecho "$num1 = $num2"
elseecho "$num2 > $num1"
fi[root@oldboy99-Kylin /server/scripts]# bash compare_2.sh 
请输入参数1、参数2:-3 a         
-3或者a不是数字
[root@oldboy99-Kylin /server/scripts]# bash compare_2.sh 
请输入参数1、参数2:-1 -3
-1 > -3
[root@oldboy99-Kylin /server/scripts]# bash compare_2.sh 
请输入参数1、参数2:30 23
30 > 23
[root@oldboy99-Kylin /server/scripts]# bash compare_2.sh 
请输入参数1、参数2:10 20  
20 > 10

2. 计算

计算方案说明应用场景
awk/bc整数、小数都可以计算计算小数、整数,或比较大小
expr计算整数检查输入的内容是否为数字(也可以用[[ =~ ]])
let/$(())/$[]计算整数配合循环使用

2.1 bc

bc:Basic calculation,基础计算

  • -l(小写的L):使用标准数学库,显示精准小数
  • 直接使用是交互式的计算器
  • 非交互式一般和echo配合使用
# 计算器
[root@oldboy99-Kylin /server/scripts]# bc
bc 1.07.1
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006, 2008, 2012-2017 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
22-10
12
10^3
1000
……
[root@oldboy99-Kylin /server/scripts]# echo "10+20" |bc
30
[root@oldboy99-Kylin /server/scripts]# echo "10-20" |bc
-10
[root@oldboy99-Kylin /server/scripts]# echo "10*20" |bc
200
[root@oldboy99-Kylin /server/scripts]# echo "10/20" |bc
0
[root@oldboy99-Kylin /server/scripts]# echo "10/20" |bc -l
.50000000000000000000
[root@oldboy99-Kylin /server/scripts]# echo "10^2" |bc 
100
[root@oldboy99-Kylin /server/scripts]# echo "10%2" |bc 
0

2.2 awk

  • -v <变量名>=<值>: 设置 awk 内部的变量值。可以使用该选项将外部值传递给 awk 脚本中的变量。
  • BEGIN关键词:BEGIN{},里面存放awk执行前的语句
[root@oldboy99-Kylin /server/scripts]# awk -v n1=10 'BEGIN{print n1}'
10
[root@oldboy99-Kylin /server/scripts]# awk -v n1=10 'BEGIN{print n1}'
10
[root@oldboy99-Kylin /server/scripts]# awk -v n1=10 -v n2=20 'BEGIN{print n1+n2}'
30
[root@oldboy99-Kylin /server/scripts]# awk -v n1=10 -v n2=20 'BEGIN{print n1-n2}'
-10
[root@oldboy99-Kylin /server/scripts]# awk -v n1=10 -v n2=20 'BEGIN{print n1*n2}'
200
[root@oldboy99-Kylin /server/scripts]# awk -v n1=10 -v n2=20 'BEGIN{print n1/n2}'
0.5
[root@oldboy99-Kylin /server/scripts]# awk -v n1=10 -v n2=20 'BEGIN{print n1^n2}'
100000000000000000000
[root@oldboy99-Kylin /server/scripts]# awk -v n1=10 -v n2=20 'BEGIN{print n1%n2}'
10
[root@oldboy99-Kylin /server/scripts]# awk -v n1=10 -v n2=20 'BEGIN{print n2%n1}'
0
# 集合变量计算
[root@oldboy99-Kylin /server/scripts]# num1=10
[root@oldboy99-Kylin /server/scripts]# num2=20
[root@oldboy99-Kylin /server/scripts]# awk -v n1=$num1 -v n2=$num2 'BEGIN{print n1}'
10
[root@oldboy99-Kylin /server/scripts]# awk -v n1=$num1 -v n2=$num2 'BEGIN{print n1+n2}'
30
[root@oldboy99-Kylin /server/scripts]# awk -v n1=$num1 -v n2=$num2 'BEGIN{print n1-n2}'
-10
[root@oldboy99-Kylin /server/scripts]# awk -v n1=$num1 -v n2=$num2 'BEGIN{print n1*n2}'
200
[root@oldboy99-Kylin /server/scripts]# awk -v n1=$num1 -v n2=$num2 'BEGIN{print n1/n2}'
0.5
[root@oldboy99-Kylin /server/scripts]# awk -v n1=$num1 -v n2=$num2 'BEGIN{print n2^n1}'
10240000000000
[root@oldboy99-Kylin /server/scripts]# awk -v n1=$num1 -v n2=$num2 'BEGIN{print n2%n1}'
0
[root@oldboy99-Kylin /server/scripts]# awk -v n1=$num1 -v n2=$num2 'BEGIN{print n1%n2}'
10

2.3 expr

expr:evaluate expressions,计算表达式

  • 一般用来验证变量是否是数字
  • 也能计算字符串长度
# 数字与算数字符之间要有空格
[root@oldboy99-Kylin /server/scripts]# expr 10 + 20
30
[root@oldboy99-Kylin /server/scripts]# expr 10 - 20
-10
[root@oldboy99-Kylin /server/scripts]# expr 10 * 20
expr: 语法错误:未预期的参数 “api.txt”
# 要用转义字符
[root@oldboy99-Kylin /server/scripts]# expr 10 \* 20
200
# expr只能计算整数,结果也只能是整数
[root@oldboy99-Kylin /server/scripts]# expr 10 / 20
0
# 判断变量是否是数字
[root@oldboy99-Kylin /server/scripts]# num=10
[root@oldboy99-Kylin /server/scripts]# expr $num + 1
11
[root@oldboy99-Kylin /server/scripts]# echo $?
0
[root@oldboy99-Kylin /server/scripts]# name=skx
[root@oldboy99-Kylin /server/scripts]# expr $name + 1
expr: 非整数参数
[root@oldboy99-Kylin /server/scripts]# echo $?
2
# 计算字符串长度
[root@oldboy99-Kylin /server/scripts]# expr length skx123oldboy
12
[root@oldboy99-Kylin /server/scripts]# expr length $name
3
# 变量扩展符也能显示字符长度
[root@oldboy99-Kylin /server/scripts]# echo ${#name}
3

2.4 let

let 命令是 BASH 中用于计算的工具,用于执行一个或多个表达式,变量计算中不需要加上 $ 来表示变量。如果表达式中包含了空格或其他特殊字符,则必须引起来。

  • let的结果必须用变量来接收,并直接修改原变量内容
  • let的结果只能是整数
[root@oldboy99-Kylin /server/scripts]# echo $n
10
[root@oldboy99-Kylin /server/scripts]# let n=10+2
[root@oldboy99-Kylin /server/scripts]# echo $n
12
[root@oldboy99-Kylin /server/scripts]# let n=10-2
[root@oldboy99-Kylin /server/scripts]# echo $n
8
[root@oldboy99-Kylin /server/scripts]# let n=10*2
[root@oldboy99-Kylin /server/scripts]# echo $n
20
[root@oldboy99-Kylin /server/scripts]# let n=10/2
[root@oldboy99-Kylin /server/scripts]# echo $n
5
[root@oldboy99-Kylin /server/scripts]# let n=10^2
[root@oldboy99-Kylin /server/scripts]# echo $n
8
[root@oldboy99-Kylin /server/scripts]# let n=10%2
[root@oldboy99-Kylin /server/scripts]# echo $n
0
[root@oldboy99-Kylin /server/scripts]# let n=10/3
[root@oldboy99-Kylin /server/scripts]# echo $n
3
# 使用let自增或自减
[root@oldboy99-Kylin /server/scripts]# let n++
[root@oldboy99-Kylin /server/scripts]# echo $n
4
[root@oldboy99-Kylin /server/scripts]# let n--
[root@oldboy99-Kylin /server/scripts]# echo $n
3

2.5 案例-计算内存的空闲率

  • 注意单位
[root@oldboy99-Kylin /server/scripts]# free -k |awk 'NR==2{print $NF/$2*100"%"}'
55.9613%
[root@oldboy99-Kylin /server/scripts]# free -m |awk 'NR==2{print $NF/$2*100"%"}'
55.8017%

2.6 案例-检查域名过期时间和https整数过期时间

  • 检查域名过期时间:whois 二级域名,关键词:Expiration Date
  • 检查https证书过期时间:curl -v https://www.二级域名,关键词:expire date
  • -v:显示请求与响应的详细信息
  • date
  • -d " ":读取字符串时间
  • +%s:获取时间戳
[root@oldboy99-Kylin /server/scripts]# cat check_domain_https_expire.sh
#!/bin/bash
##############################################################
# File Name: check_domain_https_expire.sh
# Version: V1.0
# Author: SunKexu
# Organization: www.oldboyedu.com
# Description:检查域名和https证书过期时间
##############################################################
export LANG=en_US.UTF-8
# vars
time_stamp=`date +%s`# command
while true
do
# 用户需要输入一个二级域名read -p "请输入一个二级域名:" domain
# 检查用户输入的域名[[ $domain =~ ^[^\ ]+\.[a-z]+$ ]] || {echo "输入的二级域名有误,请重新输入"continue}
# 检查域名过期时间expire_domain=`date -d $(whois ${domain} |awk -F ': ' '/Expiration Date/{print $2}') +%s`
# 检查https证书过期时间expire_https=`date -d "$(curl -v https://www.${domain} |& awk -F ': ' '/expire date/{print $2}')" +%s`
# 计算相差时间days_domain=`echo "(${expire_domain}-${time_stamp})/60/60/24" |bc`days_https=`echo "(${expire_https}-${time_stamp})/60/60/24" |bc`
cat <<EOF${domain}:域名还有${days_domain}天过期"https证书还有${days_https}天过期"
EOFexit 
done
[root@oldboy99-Kylin /server/scripts]# bash check_domain_https_expire.sh
请输入一个二级域名:baidu 123.com  
输入的二级域名有误,请重新输入
请输入一个二级域名:baidu.combaidu.com:域名还有1222天过期"https证书还有62天过期"

3. 循环

3.1 循环控制语句

循环控制说明
exit退出脚本
continue跳过本次循环,进入下一次循环
break打断,结束循环
return函数返回值

3.2 for循环-c语言格式

[root@oldboy99-Kylin /server/scripts]# cat test.sh
#!/bin/bash
##############################################################
# File Name: test.sh
# Version: V1.0
# Author: SunKexu
# Organization: www.oldboyedu.com
# Description:
##############################################################
for(( i=1;i<=10;i++))
doecho $i
done
[root@oldboy99-Kylin /server/scripts]# bash test.sh
1
2
3
4
5
6
7
8
9
10

3.3 while循环

3.3.1 案例-猜数字

  • 生成随机数:$RANDOM,随机数范围:0-32767
  • 32767是16位二进制无符号整数,数值位全为1

在这里插入图片描述

  • 生成1-100之间的随机数:$RANDOM%100+1
[root@aliyun-ubuntu /server/scripts]# cat GuessNumber.sh
#!/bin/bash
##############################################################
# File Name: GuessNumber.sh
# Version: V1.0
# Author: SunKexu
# Organization: www.oldboyedu.com
# Description:Guess the numbers
##############################################################
export LANG=en_US.UTF-8# vars
# random num
num=$(($RANDOM%100+1))# command
while true
doread -p "Please enter the number you guessed (1-100):" user# check user para[[ $user =~ ^[0-9]+$ ]] || {echo "Please enter a number (1-100):"continue}if [ $user -eq $num ];thenecho "Congratulations, you guessed right"exitelif [ $user -gt $num ];thenecho "Guess too big"elseecho "Guess too small"fi
done[root@aliyun-ubuntu /server/scripts]# bash GuessNumber.sh
Please enter the number you guessed (1-100):50
Guess too small
Please enter the number you guessed (1-100):60
Guess too small
Please enter the number you guessed (1-100):70
Guess too small
Please enter the number you guessed (1-100):80
Guess too big
Please enter the number you guessed (1-100):75
Guess too big
Please enter the number you guessed (1-100):74
Guess too big
Please enter the number you guessed (1-100):73
Guess too big
Please enter the number you guessed (1-100):72
Congratulations, you guessed right

3.3.2 读取文件

  • while读取文件时是按行读取的
[root@aliyun-ubuntu /server/scripts]# cat read_file.sh 
#!/bin/bash
##############################################################
# File Name: read_file.sh
# Version: V1.0
# Author: SunKexu
# Organization: www.oldboyedu.com
# Description:
##############################################################
export LANG=en_US.UTF-8# vars
file=$1
# check para
[ $# -eq 0 ] && {echo "Usage:$0 filename"exit 1
}
while read line
doecho $line
done < $file
[root@aliyun-ubuntu /server/scripts]# bash read_file.sh /etc/passwd |head
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin

3.3.3 案例-读取文件,批量ping和wget

  • ping -W 数字:每次请求的超时时间,单位秒
  • wget:
  • -S/–spider:不下载任何文件
  • -T 数字:设置连接请求的超时时间,单位秒
  • -t 数字:设置重试次数
[root@oldboy99-Kylin /server/scripts]# cat check_ping_wget.sh 
#!/bin/bash
##############################################################
# File Name: check_ping_wget.sh
# Version: V1.0
# Author: SunKexu
# Organization: www.oldboyedu.com
# Description:读取文件,批量ping和wget
##############################################################
export LANG=en_US.UTF-8# vars
file=$1# command
[ $# -eq 0 ] && {echo "$0 filename(has ip/domain ……)"exit 1
}
while read line
doping -c 2 -W 1 $line >/dev/null 2>&1[ $? -eq 0 ] && echo "$line 可以ping通" || echo "$line 不能ping通"wget -S -T 1 -t 1 $line >/dev/null 2>&1[ $? -eq 0 ] && echo "$line 可以访问" || echo "$line 不能访问"echo "-----------------------"
done < $1
[root@oldboy99-Kylin /server/scripts]# bash check_ping_wget.sh ./log/ip.txt 
10.0.0.200 可以ping通
10.0.0.200 不能访问
-----------------------
baidu.com 可以ping通
baidu.com 可以访问
-----------------------
jd.com 可以ping通
jd.com 可以访问
-----------------------
csdn.net 可以ping通
csdn.net 可以访问
-----------------------

4. 踩坑记录

1. -bash: 条件表达式中有语法错误

在这里插入图片描述

修改:

  • 空格:[:space:]

在这里插入图片描述

  • 或者将空格转义

在这里插入图片描述

5. 思维导图

【金山文档 | WPS云文档】 思维导图 https://kdocs.cn/l/co3I7PtpTYQX

http://www.xdnf.cn/news/12693.html

相关文章:

  • 使用Conda管理服务器多版本Python环境的完整指南
  • Java毕业设计:办公自动化系统的设计与实现
  • 不等式是否满足约束并输出最大差 - 华为OD机试真题(JavaScript 题解)
  • Python60日基础学习打卡Day46
  • 《高等数学》(同济大学·第7版)第二章第四节“隐函数及由参数方程所确定的函数的导数“
  • vue3单独封装表单校验函数
  • 使用 Laravel 中的自定义存根简化工作
  • 【笔记】WSL 中 Rust 安装与测试完整记录
  • 数控滑台技术革新:实现高效精密加工的全面探索
  • 深入剖析MySQL存储架构,索引结构,日志机制,事务提交流程
  • Java基于SpringBoot的校园闲置物品交易系统,附源码+文档说明
  • 《操作系统真相还原》——初探进程
  • 算法-多条件排序
  • 打卡day47
  • Coderider 试用报告
  • 1Panel运行的.net程序无法读取系统字体(因为使用了docker)
  • 硬盘寻址全解析:从 CHS 三维迷宫到 LBA 线性王国
  • 栈(Stack)的学习指南
  • 嵌入式学习笔记 - freeRTOS xTaskResumeAll( )函数解析
  • frida简介及环境搭建
  • 【数据结构】6. 时间与空间复杂度
  • AI-Sphere-Butler之如何启动AI全能管家教程(WSL测试环境下适用)
  • C++修炼:C++11(二)
  • GPT-5:不止于回答,AI学会了“思考”
  • MVC分层架构模式深入剖析
  • 2025年—Comfyui聚合插件:Comfyui-LayerStyle 超多实用功能 | 附各功能模型
  • 【R语言编程——数据调用】
  • SpringBoot-17-MyBatis动态SQL标签之常用标签
  • 【MySQL】10.事务管理
  • C++刷题:日期模拟(1)