3、read交互式传参
1. [root@LB00 Day02]# cat jisuanqi_3.sh 2. #!/bin/bash 3. read -p "请输入第一个数字:" num1 4. read -p "请输入第二个数字:" num2 5. echo $num1+$num2=$[$num1+$num2] 6. echo $num1-$num2=$[$num1-$num2] 7. echo $num1*$num2=$[$num1*$num2] 8. echo $num1/$num2=$[$num1/$num2] 9. echo $num1%$num2=$[$num1%$num2] 10. echo $num1^$num2=$[$num1^$num2] 11. [root@LB00 Day02]# sh jisuanqi_3.sh 12. 请输入第一个数字:9 13. 请输入第二个数字:3 14. 9+3=12 15. 9-3=6 16. 9*3=27 17. 9/3=3 18. 9%3=0 19. 9^3=10
4、交互式传参,可以填运算符
1. [root@LB00 Day02]# cat jisuanqi_4.sh 2. #!/bin/bash 3. read -p "请输入第一个数字:" num1 4. read -p "请输入运算符号:" fuhao 5. read -p "请输入第二个数字:" num2 6. if [ $fuhao == "+" ] 7. then 8. echo $num1+$num2=$[$num1+$num2] 9. elif [ $fuhao == "-" ] 10. then 11. echo $num1-$num2=$[$num1-$num2] 12. elif [ $fuhao == "*" ] 13. then 14. echo $num1*$num2=$[$num1*$num2] 15. elif [ $fuhao == "/" ] 16. then 17. echo $num1/$num2=$[$num1/$num2] 18. elif [ $fuhao == "%" ] 19. then 20. echo $num1%$num2=$[$num1%$num2] 21. elif [ $fuhao == "^" ] 22. then 23. echo $num1^$num2=$[$num1^$num2] 24. else 25. echo 没有该运算符号 26. fi 27. [root@LB00 Day02]# sh jisuanqi_4.sh 28. 请输入第一个数字:6 29. 请输入运算符号:+ 30. 请输入第二个数字:1 31. 6+1=7 32. [root@LB00 Day02]# sh jisuanqi_4.sh 33. 请输入第一个数字:9 34. 请输入运算符号:/ 35. 请输入第二个数字:3 36. 9/3=3
5、赋值传参,可以算小数
将外面参数赋值给变量,又将变量赋值到awk里
1. [root@LB00 Day02]# cat jisuanqi_5.sh 2. #!/bin/bash 3. num1=$1 4. num2=$2 5. echo $num1+$num2=`awk -v num1="$num1" -v num2="$num2" 'BEGIN{print num1+num2}'` 6. echo $num1-$num2=`awk -v num1="$num1" -v num2="$num2" 'BEGIN{print num1-num2}'` 7. echo $num1*$num2=`awk -v num1="$num1" -v num2="$num2" 'BEGIN{print num1*num2}'` 8. echo $num1/$num2=`awk -v num1="$num1" -v num2="$num2" 'BEGIN{print num1/num2}'` 9. echo $num1%$num2=`awk -v num1="$num1" -v num2="$num2" 'BEGIN{print num1%num2}'` 10. echo $num1^$num2=`awk -v num1="$num1" -v num2="$num2" 'BEGIN{print num1^num2}'` 11. [root@LB00 Day02]# sh jisuanqi_5.sh 10 3 12. 10+3=13 13. 10-3=7 14. 10*3=30 15. 10/3=3.33333 16. 10%3=1 17. 10^3=1000 18. 19. # 其实不用两次赋值的,awk在脚本中使用方式如下 20. 21. [root@LB00 Day02]# cat jisuanqi_6.sh 22. #!/bin/bash 23. num1=$1 24. num2=$2 25. echo "$num1+$num2=`awk "BEGIN{print $num1+$num2}"`" 26. echo "$num1-$num2=`awk "BEGIN{print $num1-$num2}"`" 27. echo "$num1*$num2=`awk "BEGIN{print $num1*$num2}"`" 28. echo "$num1/$num2=`awk "BEGIN{print $num1/$num2}"`" 29. echo "$num1%$num2=`awk "BEGIN{print $num1%$num2}"`" 30. echo "$num1^$num2=`awk "BEGIN{print $num1^$num2}"`" 31. [root@LB00 Day02]# sh jisuanqi_6.sh 10 3 32. 10+3=13 33. 10-3=7 34. 10*3=30 35. 10/3=3.33333 36. 10%3=1 37. 10^3=1000
整数比较
一、比较符
-eq 相等
-ge 大于或等于
-gt 大于
-le 小于或等于
-lt 小于
-ne 不相等
二、语法
1、test 整数1 比较符 整数2
1. [root@LB00 ~]# test 1 -eq 1 2. [root@LB00 ~]# echo $? 3. 0 #0即成立,非0不成立 4. [root@LB00 ~]# test 1 -ne 1 5. [root@LB00 ~]# echo $? 6. 1
2、[ 整数1 比较符 整数2 ] 注意两边都有空格
1. [root@LB00 ~]# [ 100 -eq 100 ] 2. [root@LB00 ~]# echo $? 3. 0 4. [root@LB00 ~]# [ 100 -lt 100 ] 5. [root@LB00 ~]# echo $? 6. 1 7. [root@LB00 ~]# [ 100 -lt 100 ] && echo 成立 || echo 不成立 8. 不成立 9. [root@LB00 ~]# [ 100 -eq 100 ] && echo 成立 || echo .成立 10. 成立
3、表达式中都支持变量
1. [root@LB00 ~]# num1=100 2. [root@LB00 ~]# num2=100 3. [root@LB00 ~]# [ $num1 -eq $num2 ] && echo 成立 || echo 不成立 4. 成立
4、表达式中都支持命令
1. [root@LB00 Day02]# [ `echo 100` -lt `cat /etc/passwd|wc -l ` ] && echo 成立 || echo 不成立 2. 不成立 3. [root@LB00 Day02]# cat /etc/passwd|wc -l 4. 22
5、多整数比较
-o or 或者
-a and 并且
注意:在表达式 (())中使用的比较符是> < >= <= != && ||
1. [root@LB00 Day02]# [ 10 -eq 10 -o 100 -gt 20 ] && echo 成立 || echo 不成立 2. 成立 3. [root@LB00 Day02]# [ 10 -eq 10 -o 100 -lt 20 ] && echo 成立 || echo 不成立 4. 成立 5. [root@LB00 Day02]# [ 10 -ne 10 -o 100 -lt 20 ] && echo 成立 || echo 不成立 6. 不成立 7. [root@LB00 Day02]# (( 10 > 2)) && echo 成立 || echo 成立 8. 成立 9. [root@LB00 Day02]# (( 10 != 2 )) && echo 成立 || echo 不成立 10. 成立 11. [root@LB00 Day02]# (( 10 == 2 )) && echo 成立 || echo 不成立 12. 不成立 13. [root@LB00 Day02]# (( 10 == 2 || 5 > 1 )) && echo 成立 || echo 不成立 14. 成立 15. [root@LB00 Day02]# (( 10 == 2 && 5 < 1 )) && echo 成立 || echo 不成立 16. 不成立
三、示例
1、统计磁盘使用率,大于10%则告警发送邮件,小于10%则提示磁盘使用正常,当前使用率是多少
1. [root@LB00 Day02]# df -h 2. Filesystem Size Used Avail Use% Mounted on 3. devtmpfs 476M 0 476M 0% /dev 4. tmpfs 487M 0 487M 0% /dev/shm 5. tmpfs 487M 14M 473M 3% /run 6. tmpfs 487M 0 487M 0% /sys/fs/cgroup 7. /dev/sda3 19G 2.0G 17G 11% / 8. /dev/sda1 197M 110M 88M 56% /boot 9. tmpfs 98M 0 98M 0% /run/user/0 10. [root@LB00 Day02]# cat gaojing.sh 11. #!/bin/bash 12. #1、获取磁盘使用率 13. use_disk=$(df -h|grep /dev/sda3|awk '{print $5}') 14. 15. #2、整数比较 16. if [ ${use_disk%\%} -gt 10 ] 17. then 18. echo 当前的磁盘使用率:$use_disk > /tmp/disk.log 19. mail -s "磁盘使用率告警通知" xxx@qq.com < /tmp/disk.log #需要提前配置好邮箱 20. i=1 21. else 22. echo 当前磁盘使用正常,使用率为$use_disk 23. fi 24. 25. sleep 60 #可以暂停60秒,查看是否恢复 26. 27. if [ $i -eq 1 && ${use_disk%\%} -lt 10 ] 28. then 29. echo 恢复...... 30. fi
依照上面操作还可以写出内存使用率告警和负载使用告警
2、内存使用率告警
1. [root@LB00 Day02]# free #里面used除以total乘以100%就是内存使用率 2. total used free shared buff/cache available 3. Mem: 995676 152768 467416 14060 375492 685652 4. Swap: 1048572 0 1048572 5. [root@LB00 Day02]# cat free.sh 6. #!/bin/bash 7. used=`free | grep Mem | awk '{print $3}'` 8. total=`free | grep Mem | awk '{print $2}'` 9. if [ "$total" -ne "0" ] 10. then 11. free=$((used*100/total)) 12. else 13. echo "Error: Total memory is zero." 14. fi 15. if [ ${free%\%} -gt 15 ] 16. then 17. echo 当前内存使用率超过15%,为$free% 18. exit 19. fi 20. echo 当前内存使用率正常,为$free% 21. [root@LB00 Day02]# sh free.sh 22. 15 23. 当前内存使用率正常,为15%
3、负载使用率告警
1. [root@LB00 Day02]# cat uptime.sh 2. #!/bin/bash 3. load1=`uptime|awk -F , '{print $(NF-2)}'|awk '{print $3}'` 4. load2=`uptime|awk -F , '{print $(NF-1)}'|awk '{print $1}'` 5. load3=`uptime|awk -F , '{print $NF}'|awk '{print $1}'` 6. load_avg=`awk -v load1=$load1 -v load2=$load2 -v load3=$load3 'BEGIN{print (load1+load2+load3)/3}'` 7. if [ $(echo "$load_avg > 0.5" | bc) -eq 1 ] 8. then 9. echo 当前1、5、15分钟平均负载超过0.5,为$load_avg 10. exit 11. fi 12. echo 当前1、5、15分钟平均负载正常为$load_avg 13. [root@LB00 Day02]# sh uptime.sh 14. 当前1、5、15分钟平均负载正常为0.02
文件判断
一、判断符
-f 文件存在则为真
-d 目录存在则为真
-e 文件存在则为真(任意类型)
-r 文件可读则为真
-w 文件可写则为真
-x 文件可执行则为真
二、语法
1、test 判断符 文件或目录
1. [root@LB00 Day02]# test -f /etc/passwd && echo 为真 || echo 为假 2. 为真 3. [root@LB00 Day02]# test -d /etc/passwd && echo 为真 || echo 为假 4. 为假 5. [root@LB00 Day02]# test -e /etc/passwd && echo 为真 || echo 为假 6. 为真 7. [root@LB00 Day02]# test -r /etc/passwd && echo 为真 || echo 为假 8. 为真 9. [root@LB00 Day02]# test -w /etc/passwd && echo 为真 || echo 为假 10. 为真 11. [root@LB00 Day02]# test -x /etc/passwd && echo 为真 || echo 为假 12. 为假
2、[ 判断符 文件或目录 ]
1. [root@LB00 Day02]# [ -f /etc/ ] && echo 为真 || echo 为假 2. 为假 3. [root@LB00 Day02]# [ -d /etc/ ] && echo 为真 || echo 为假 4. 为真 5. [root@LB00 Day02]# [ -e /etc/ ] && echo 为真 || echo 为假 6. 为真 7. [root@LB00 Day02]# [ -r /etc/ ] && echo 为真 || echo 为假 8. 为真 9. [root@LB00 Day02]# [ -w /etc/ ] && echo 为真 || echo 为假 10. 为真 11. [root@LB00 Day02]# [ -x /etc/ ] && echo 为真 || echo 为假 12. 为真
三、示例
1、目录存在则不管,不存在则创建
[root@LB00 Day02]# [ -d 10.0.0.8_2022_02_11 ] || mkdir 10.0.0.8_2022_02_11
2、目录存在则打包
1. [root@LB00 Day02]# [ -d /etc/ ] && mkdir /opt/`hostname`_`date +%F` && tar zcvf /opt/`hostname`_`date +%F`/etc.tar.gz /etc 2. [root@LB00 Day02]# tree /opt/ 3. /opt/ 4. └── LB00_2023-05-15 5. └── etc.tar.gz 6. 7. 1 directory, 1 file
3、bash脚本变量在当前shell中调用
1. [root@LB00 Day02]# cat env.sh 2. num1=100 3. num2=200 4. num3=300 5. [root@LB00 Day02]# [ -f env.sh ] && source env.sh && echo $num1 #夫shell调用子shell变量 6. 100 7. 8. [root@LB00 Day02]# cat env.sh 9. num1=100 10. num2=200 11. [root@LB00 Day02]# cat test.sh 12. #!/bin/bash 13. [ -f /server/scripts/Day02/env.sh ] && . /server/scripts/Day02/env.sh #不同子shell之间调用 14. echo $num1+$num2=$[$num1 + $num2] 15. [root@LB00 Day02]# sh test.sh 16. 100+200=300 17. 18. [root@LB00 Day02]# cat ~/.bash_profile #-f系统案例 19. # .bash_profile 20. 21. # Get the aliases and functions 22. if [ -f ~/.bashrc ]; then 23. . ~/.bashrc 24. fi 25. ......
字符串比对
==、!=,也可以结合-o、-a
-z,检查字符串是否为空,字符串为空为真,-n,检查字符串是否为非空,字符串不为空为真
注意使用变量比对大部分情况下要加引号,特别是read的变量,否则直接回车不输入信息就会报错
1. [root@LB00 Day02]# [ root == root ] && echo 等于 || echo 不等于 2. 等于 3. [root@LB00 Day02]# [ root == roo ] && echo 等于 || echo 不等于 4. 不等于 5. [root@LB00 Day02]# [ root == roo -o yes == yes ] && echo 等.于 | echo 不等于 6. 等于 7. [root@LB00 Day02]# [ -z "" ] && echo 字符串空 || echo 字符串非空 8. 字符串空 9. [root@LB00 Day02]# [ -z "1" ] && echo 字符串空 || echo 字符串非空 10. 字符串非空 11. [root@LB00 Day02]# [ -n "" ] && echo 字符串非空 || echo 字符串空 12. 字符串空 13. [root@LB00 Day02]# [ -n "1" ] && echo 字符串非空 || echo 字符串空 14. 字符串非空
正则比对
=~ 模糊匹配
1. [root@LB00 Day02]# [[ root =~ roo ]] && echo 匹配成功 || echo 匹配失败 2. 匹配成功 3. [root@LB00 Day02]# [[ root =~ r ]] && echo 匹配成功 || echo 匹配失败 4. 匹配成功 5. [root@LB00 Day02]# [[ root =~ ^r ]] && echo 匹配成功 || echo 匹配失败 6. 匹配成功 7. [root@LB00 Day02]# [[ root =~ ^r$ ]] && echo 匹配成功 || echo 匹配失败 8. 匹配失败 9. [root@LB00 Day02]# [[ root =~ ^r.*t$ ]] && echo 匹配成 功 | echo 匹配失败 10. 匹配成功 11. [root@LB00 Day02]# [[ root =~ [a-z] ]] && echo 匹配成功 || eccho 匹配失败 12. 匹配成功 13. [root@LB00 Day02]# [[ root =~ [0-9] ]] && echo 匹配成功 || echo 匹配失败 14. 匹配失败 15. [root@LB00 Day02]# [[ root =~ ^[a-z]+$ ]] && echo 匹配成功 || echo 匹配失败 16. 匹配成功 17. [root@LB00 Day02]# [[ root1 =~ ^[a-z]+$ ]] && echo 匹配成功 | echo 匹配失败 18. 匹配失败 19. [root@LB00 Day02]# [[ r1o2o3t =~ [0-9] ]] && echo 匹配 成功 | echo 匹配失败 20. 匹配成功 21. [root@LB00 Day02]# [[ r1o2o3t =~ [a-z]+ ]] && echo 匹.成功 || echo 匹配失败 22. 匹配成功 23. [root@LB00 Day02]# [[ r1o2o3t =~ ^[a-z]+$ ]] && echo .配成功 || echo 匹配失败 24. 匹配失败 25. [root@LB00 Day02]# [[ r1o2o3t =~ ^[a-z]$ ]] && echo 匹 配成功 || echo 匹配失败 26. 匹配失败
示例一:控制输入内容格式
控制姓名年龄的格式,年龄控制在18-256之间可以正常往后运行
1. [root@LB00 Day02]# cat read.sh 2. #!/bin/bash 3. read -p "请输入您的姓名:" name 4. if [[ ! $name =~ ^[a-z]+$ ]] 5. then 6. echo "请输入正确姓名,不能有数字" 7. exit 8. fi 9. read -p "请输入您的年龄:" age 10. if [[ ! $age =~ ^[0-9]+$ ]] 11. then 12. echo "请输入正确年龄,不能有英文" 13. exit 14. fi 15. if ! [ $age -ge 18 -a $age -le 256 ] 16. then 17. echo "您的年龄不符合标准" 18. exit 19. fi 20. echo "姓名为" $name "年龄为" $age 21. [root@LB00 Day02]# sh read.sh 22. 请输入您的姓名:q 23. 请输入您的年龄:18 24. 姓名为 q 年龄为 18 25. [root@LB00 Day02]# sh read.sh 26. 请输入您的姓名:q1q 27. 请输入正确姓名,不能有数字 28. [root@LB00 Day02]# sh read.sh 29. 请输入您的姓名:q 30. 请输入您的年龄:17 31. 您的年龄不符合标准 32. [root@LB00 Day02]# sh read.sh 33. 请输入您的姓名:qq 34. 请输入您的年龄:333 35. 您的年龄不符合标准
扩展(配合三剑客取系统信息)
写脚本常常需要三剑客命令的配合,所以我们进行如下练习,练习使用三剑客命令。
写一个脚本,统计出系统主机名称,eth0IP地址,公网ip地址,平台信息,系统版本号,内核版本号,磁盘使用率,内存使用率。
这种脚本可以放到/etc/profile中,xshell一连接就能看到,工作中常常需要看负载信息,这样一连接信息都出来了,比较方便。
1. [root@LB00 Day02]# cat tongji.sh 2. #!/bin/bash 3. hostname=$(hostname) 4. eth0_ip=$(ip a|grep eth0|grep inet|awk '{print $2}') 5. gong_ip=$(curl -s cip.cc|awk 'NR==1{print $3}') 6. pingtai=$(hostnamectl|grep Virtualization|awk '{print $2}') 7. linux_banben=$(cat /etc/redhat-release) 8. linux_neihe=$(hostnamectl|grep Kernel|awk '{print $2,$3}') 9. load1=`uptime|awk -F , '{print $(NF-2)}'|awk '{print $3}'` 10. load2=`uptime|awk -F , '{print $(NF-1)}'|awk '{print $1}'` 11. load3=`uptime|awk -F , '{print $NF}'|awk '{print $1}'` 12. load_avg=`awk -v load1=$load1 -v load2=$load2 -v load3=$load3 'BEGIN{print (load1+load2+load3)/3}'` 13. free=$(free | grep Mem | awk '{print $3/$2 *100}') 14. use_disk=$(df -h|grep /dev/sda3|awk '{print $5}') 15. 16. echo 系统主机名称为:$hostname 17. echo eth0的IP为:$eth0_ip 18. echo 公网IP为:$gong_ip 19. echo 平台信息为:$pingtai 20. echo 系统版本为:$linux_banben 21. echo 内核版本为:$linux_neihe 22. echo 1,5,15分钟平均负载为:$load_avg 23. echo 内存使用率为:$free% 24. echo 磁盘使用率为:$use_disk 25. [root@LB00 Day02]# sh tongji.sh 26. 系统主机名称为:LB00 27. eth0的IP为:10.0.0.4/24 28. 公网IP为:123.112.17.24 29. 平台信息为:vmware 30. 系统版本为:CentOS Linux release 7.9.2009 (Core) 31. 内核版本为:Linux 3.10.0-1160.el7.x86_64 32. 1,5,15分钟平均负载为:0.02 33. 内存使用率为:15.5713% 34. 磁盘使用率为:11% 35. [root@LB00 Day02]# scp tongji.sh 10.0.0.7:/root/ 36. 37. [root@Web01 ~]# sh tongji.sh 38. 系统主机名称为:Web01 39. eth0的IP为:10.0.0.7/24 40. 公网IP为:123.112.17.24 41. 平台信息为:vmware 42. 系统版本为:CentOS Linux release 7.9.2009 (Core) 43. 内核版本为:Linux 3.10.0-1160.el7.x86_64 44. 1,5,15分钟平均负载为:0.0233333 45. 内存使用率为:50.3111% 46. 磁盘使用率为:17% 47. 48. [root@LB00 Day02]# tail -1 /etc/profile 49. sh /server/scripts/Day02/tongji.sh
我是koten,10年运维经验,持续分享运维干货,感谢大家的阅读和关注!