30、 shell脚本进阶
shell脚本if+case
一、条件测试
1.1、条件测试:$?----返回码,判断命令或者脚本是否执行成功(最近的一条)
0 true 为真就是成功 成立
非0 false 失败或者异常。
二、test命令
test命令:可以进行条件测试,然后根据返回值来判断条件是否成立。
test -e :测试文件或者目录是否存在。
[root@localhost opt]# test -e 123 [root@localhost opt]# echo $? 0
test -d:测试目录是否存在
[root@localhost opt]# test -d 123 [root@localhost opt]# echo $? 1 [root@localhost opt]# mkdir 345 [root@localhost opt]# test -d 345 [root@localhost opt]# echo $? 0
test -f:测试文件是否存在
[root@localhost opt]# test -f 123 [root@localhost opt]# echo $? 0
test -e=test -d +test -f
test -r:测试当前用户对文件或目录是否由读权限
test -w:测试当前用户对文件或目录是否由写权限
test -x:测试当前用户对文件或目录是否由执行权限
-rw-r--r--. 1 root root 0 6月 11 22:49 123 drwxr-xr-x. 2 root root 6 6月 12 09:37 345 -rwxrwxrwx. 1 xy102 xy102 38 5月 21 15:36 login.sh drwxr-xr-x. 9 dn dn 186 5月 22 20:07 nginx-1.22.0 -rw-r--r--. 1 root root 1073322 5月 22 09:32 nginx-1.22.0.tar.gz -rw-r--r--. 1 root root 7 6月 11 10:23 passwd.txt -rw-r--r--. 1 root root 111 6月 11 10:18 test1 -rw-r--r--. 1 root root 108 6月 11 15:07 test1.sh -rw-r--r--. 1 root root 225 6月 11 16:12 test2.sh -rwxrwxrwx. 1 root root 285 6月 11 16:54 test.sh [root@localhost opt]# test -r 345 [root@localhost opt]# echo $? 0 [root@localhost opt]# test -w 345 [root@localhost opt]# echo $? 0 [root@localhost opt]# test -x 345 [root@localhost opt]# echo $? 0 [root@localhost opt]# test -x 123 [root@localhost opt]# echo $? 1 [root@localhost opt]# test -r 123 [root@localhost opt]# echo $? 0 [root@localhost opt]# test -w 123 [root@localhost opt]# echo $? 0
三、整数比较符(以下操作符只能用于整数比较)
-eq:等于 == 既可以比较整数,也可以比较字符串是否一致
-ne:不等于 != :不等于
-gt:大于 > :大于
-lt:小于
-ge:大于等于 >=:大于等于
-le:小于等于 $b )) [root@localhost opt]# echo $? 0 [root@localhost opt]# (( $a
逻辑与和逻辑或
与 :&&–条件都要满足才成立 -a
或 :||–有一个条件满足就成立 -o
[[]]中间只能写&&和||
[root@localhost opt]# b=5 [root@localhost opt]# [[ $b -gt 4 && $b -lt 6 ]] [root@localhost opt]# echo $? 0 [root@localhost opt]# [[ $b -gt 4 -a $b -lt 6 ]] -bash: 条件表达式中有语法错误 -bash: `-a' 附近有语法错误
[root@localhost opt]# [ $a -ge 8 || $a -le 4 ] -bash: [: 缺少 `]' bash: 5: 未找到命令... [root@localhost opt]# [[ $a -ge 8 || $a -le 4 ]] [root@localhost opt]# echo $? 1
四、if语句:
4.1、单分支结构:
[root@localhost opt]# vim if.sh if [ 3 -gt 2 ] then echo "ok" fi #if后面是条件测试语句 #then 下面是命令序列,只有条件测试语句成立,才会执行then的命令 模块。 #fi 结束语句 [root@localhost opt]# sh if.sh ok
[root@localhost opt]# vim if.sh if [ 3 -gt 4 ] then echo "ok" fi #if后面是条件测试语句 #then 下面是命令序列,只有条件测试语句成立,才会执行then的命令 模块。 #fi 结束语句 [root@localhost opt]# sh if.sh
4.2、双分支结构
[root@localhost opt]# vim if.sh #双分支结构 if [ 3 -gt 4 ] then echo "ok" else echo "no" fi #条件满足执行then,不满足执行else,执行完毕,语句结束。 [root@localhost opt]# sh if.sh no
4.2.1、通过位置变量传参的方式,给脚本内部传一个ip地址,
ping的通的要提示用户ip is online,而且要保存到/opt/hosts.txt文件当中
如果ping不通,提示用户ip is offline。
[root@localhost opt]# vim 1.sh ping -c 3 $1 if [[ $? -eq 0 ]] then echo "ip is online" echo $1 >> /opt/hosts.txt else echo "ip is offline" fi [root@localhost opt]# sh 1.sh www.baidu.com PING www.a.shifen.com (180.101.50.188) 56(84) bytes of data. 64 bytes from 180.101.50.188 (180.101.50.188): icmp_seq=1 ttl=128 time=7.80 ms 64 bytes from 180.101.50.188 (180.101.50.188): icmp_seq=2 ttl=128 time=8.43 ms 64 bytes from 180.101.50.188 (180.101.50.188): icmp_seq=3 ttl=128 time=17.5 ms --- www.a.shifen.com ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 7.809/11.263/17.541/4.446 ms ip is online
#随机输入一个整数,read -p输入一一个数
#判断这个数是偶数还是奇数,偶数提示偶数,奇数提示奇数
[root@localhost opt]# vim 2.sh read -p "随机输入一个数" a if [[ $a%2 -eq 0 ]] then echo "提示偶数" else echo "提示奇数" fi [root@localhost opt]# sh 2.sh 随机输入一个数5 提示奇数 [root@localhost opt]# sh 2.sh 随机输入一个数4 提示偶数 ### 4.3、多分
支结构
if [] then 命令序列 elif [] then 命令序列 elif [] then 命令序列 else then 命令序列 fi
[root@localhost opt]# vim 3.sh read -p "请输入一个整数" a if [[ $a -lt 10 ]] then echo "1" elif [[ $a -gt 25 ]] then echo "2" else echo "3" fi [root@localhost opt]# sh 3.sh 请输入一个整数6 1 [root@localhost opt]# [root@localhost opt]# sh 3.sh 请输入一个整数67 2 [root@localhost opt]# sh 3.sh 请输入一个整数15 3
[root@localhost opt]# vim if4.sh read -p "请输入您的分数:" a if [[ $a -ge 85 && $a -le 100 ]] then echo "优秀" elif [[ $a -ge 70 && $a -le 84 ]] then echo "一般" elif [[ $a -ge 60 && $a -le 69 ]] then echo "合格" else echo "30遍" fi [root@localhost opt]# sh if4.sh 请输入您的分数:78 一般 [root@localhost opt]# sh if4.sh 请输入您的分数:98 优秀 [root@localhost opt]# sh if4.sh 请输入您的分数:12 30遍
4.4、嵌套if
[root@localhost opt]# vim if5.sh [root@localhost opt]# sh if5.sh 请输入您的分数:10.5 if5.sh: 第 2 行:[: 10.5: 期待整数表达式 输入错误 [root@localhost opt]# vim if5.sh read -p "请输入您的分数:" a if [ $a -eq $a ] &> /dev/null then if [[ $a -ge 85 && $a -le 100 ]] then echo "优秀" elif [[ $a -ge 70 && $a -le 84 ]] then echo "一般" elif [[ $a -ge 60 && $a -le 69 ]] then echo "合格" else echo "30遍" fi else echo "输入错误" fi [root@localhost opt]# sh if5.sh 请输入您的分数:10.9 输入错误
五、case语句
#case语句 相当于多分支结构 case 变量值 in 模式1) 命令序列 ;; 模式2) 命令序列 ;; ..... *)相当于else 命令序列 esac
六、课后练习
1.检查用户家目录中的 test.sh 文件是否存在,并且检查是否有执行权限
[root@localhost opt]# vim if11.sh test -e /root/test.sh if [[ $? -eq 0 ]] then echo "文件存在" test -x /root/test.sh if [[ $? -eq 0 ]] then echo "有执行权限" else echo "没有执行权限" fi else echo "文件不存在" fi [root@localhost opt]# sh if11.sh 文件不存在 [root@localhost opt]# cd /root [root@localhost ~]# touch test.sh [root@localhost ~]# sh if11.sh sh: if11.sh: 没有那个文件或目录 [root@localhost ~]# cd /opt [root@localhost opt]# sh if11.sh 文件存在 没有执行权限 [root@localhost opt]# cd /root [root@localhost ~]# chmod 777 test.sh [root@localhost ~]# cd /opt [root@localhost opt]# sh if11.sh 文件存在 有执行权限
2.提示用户输入100米赛跑的秒数,要求判断秒数大于0且小于等于10秒的进入选拔赛,
大于10秒的都淘汰,
如果输入其它字符则提示重新输入;进入选拔赛的成员再进一步判断男女性别。
男生进男生组,女生进女生组,如果输入错误请提示错误(整数判断,小数判断。9.72 3.21 )
vim if12.sh
read -p "提示用户输入100m赛跑的秒速:" a
if [[ $a -eq $a ]]
then
echo "整数"
if [[ $a -gt 0 && $a -le 10 ]]
then
echo "进入选拔赛"
read -p "输入性别:" b
if [[ $b == "boy" ]] ##字符串比较只能用==
then
echo "进男生组"
elif [[ $b == "girl" ]]
then
echo "进女生组"
else
echo "输入错误,提示错误"
fi
else
echo "大于10秒淘汰"
fi
else
echo "重新输入"
fi
~
[root@localhost opt]# sh if12.sh
提示用户输入100m赛跑的秒速:5
整数
进入选拔赛
输入性别:boy
进男生组
[root@localhost opt]# sh if12.sh
提示用户输入100m赛跑的秒速:7
整数
进入选拔赛
输入性别:girl
进女生组
[root@localhost opt]# sh if12.sh
提示用户输入100m赛跑的秒速:5
整数
进入选拔赛
输入性别:boy
进男生组
[root@localhost opt]# sh if12.sh
提示用户输入100m赛跑的秒速:7
整数
进入选拔赛
输入性别:girl
进女生组
[root@localhost opt]# sh if12.sh
提示用户输入100m赛跑的秒速:45
整数
大于10秒淘汰
[root@localhost opt]#
3.用case语句解压根据后缀名为 .tar.gz 或 .tar.bz2 的压缩包到 /opt 目录
tar -zxvf
tar -jxvf
[root@localhost opt]# vim if13.sh case $1 in *.tar.gz) tar -zxvf $1 -C /opt ;; *.tar.bz2) tar -jxvf $1 -C /opt ;; esac ##压缩 tar -zcvf 123.tar.gz 123 456 可以多个文件 tar -jcvf 123.tar.bz2 123 456 可以多个文件 ##解压 tar -zxvf 123.tar.gz tar -jxvf 123.tar.bz2 [root@localhost opt]# touch 123 [root@localhost opt]# touch 456 [root@localhost opt]# tar -jcvf 123.tar.bz2 123 456 123 456 [root@localhost opt]# sh 4.sh /opt/123.tar.bz2 123 456 [root@localhost opt]# rm -rf 123 456 [root@localhost opt]# ls 123.tar.bz2 2.sh 4.sh login.sh nginx-1.22.0.tar.gz 1.sh 3.sh hosts.txt nginx-1.22.0 [root@localhost opt]# sh 4.sh /opt/123.tar.bz2 123 456
4.提示用户输入内容,使用if 语句判断输入的内容是否为整数。判断范围0-100。
vim if14.sh read -p "提示用户输入内容:" a if [[ $a -eq $a ]] then echo "为整数" if [[ $a -ge 0 && $a -le 100 ]] then echo "在0-100范围内" else echo "不在0-100范围内" fi else echo "不是整数" fi [root@localhost opt]# sh if14.sh 提示用户输入内容:2324 为整数 不在0-100范围内 [root@localhost opt]# sh if14.sh 提示用户输入内容:34 为整数 在0-100范围内
5.根据上一题再判断输入的内容是奇数还是偶数。
vim if15.sh read -p "提示用户输入内容:" a if [[ $a -eq $a ]] then echo "为整数" if [[ $a -ge 0 && $a -le 100 ]] then echo "在0-100范围内" if [[ $(($a%2)) -eq 0 ]] then echo "偶数" else echo "奇数" fi else echo "不在0-100范围内" fi else echo "不是整数" fi 提示用户输入内容:68 为整数 在0-100范围内 偶数 [root@localhost opt]# sh if15.sh 提示用户输入内容:55 为整数 在0-100范围内 奇数
6.用if 语句判断主机是否存活.保存到/opt/hosts.txt
ping -c 5 不显示ping的过程
vim if16.sh ping -c 5 -q $1 if [[ $? -eq 0 ]] then echo "存活" echo $1 >> /opt/hosts.txt else echo "不存活" fi [root@localhost opt]# sh if16.sh www.baidu.com PING www.a.shifen.com (180.101.50.242) 56(84) bytes of data. --- www.a.shifen.com ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 4007ms rtt min/avg/max/mdev = 4.730/5.502/7.089/0.827 ms 存活 [root@localhost opt]# sh if16.sh www.jingdong.com PING mfn-df-sched.jcloudimg.com (222.186.184.140) 56(84) bytes of data. --- mfn-df-sched.jcloudimg.com ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 4006ms rtt min/avg/max/mdev = 5.579/8.568/17.161/4.332 ms 存活
7.用case语句控制 firewalld start|stop|restart|status 来管理firewalld服务,
要求如果命令选项不对,则提示输入不正确: {start|stop|status|restart}”。
stop start status restart
systemctl
[root@localhost opt]# vim if17.sh
read -p "输入管理防火墙的命令:" a
case $a in
start)
systemctl start firewalld
echo "开启"
;;
stop)
systemctl stop firewalld
echo "关闭防火墙"
;;
restart)
systemctl restart firewalld
echo "重启"
;;
status)
systemctl status firewalld
echo "状态"
;;
*)
echo "不正确"
esac
[root@localhost opt]# sh if17.sh
输入管理防火墙的命令:restart
重启
[root@localhost opt]# sh if17.sh
输入管理防火墙的命令:stop
关闭防火墙
[root@localhost opt]# sh if17.sh
输入管理防火墙的命令:restart
重启
[root@localhost opt]# vim if17.sh
[root@localhost opt]# sh if17.sh
输入管理防火墙的命令:status
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
Active: active (running) since 三 2024-06-12 17:08:16 CST; 2min 59s ago
Docs: man:firewalld(1)
Main PID: 15289 (firewalld)
Tasks: 2
CGroup: /system.slice/firewalld.service
└─15289 /usr/bin/python -Es /usr/sbin/firewall...
6月 12 17:08:17 localhost.localdomain firewalld[15289]: ...
6月 12 17:08:17 localhost.localdomain firewalld[15289]: ...
6月 12 17:08:17 localhost.localdomain firewalld[15289]: ...
6月 12 17:08:17 localhost.localdomain firewalld[15289]: ...
6月 12 17:08:17 localhost.localdomain firewalld[15289]: ...
6月 12 17:08:17 localhost.localdomain firewalld[15289]: ...
6月 12 17:08:17 localhost.localdomain firewalld[15289]: ...
6月 12 17:08:17 localhost.localdomain firewalld[15289]: ...
6月 12 17:08:17 localhost.localdomain firewalld[15289]: ...
6月 12 17:08:17 localhost.localdomain firewalld[15289]: ...
Hint: Some lines were ellipsized, use -l to show in full.
状态
roup: /system.slice/firewalld.service
└─15289 /usr/bin/python -Es /usr/sbin/firewall…
6月 12 17:08:17 localhost.localdomain firewalld[15289]: …
6月 12 17:08:17 localhost.localdomain firewalld[15289]: …
6月 12 17:08:17 localhost.localdomain firewalld[15289]: …
6月 12 17:08:17 localhost.localdomain firewalld[15289]: …
6月 12 17:08:17 localhost.localdomain firewalld[15289]: …
6月 12 17:08:17 localhost.localdomain firewalld[15289]: …
6月 12 17:08:17 localhost.localdomain firewalld[15289]: …
6月 12 17:08:17 localhost.localdomain firewalld[15289]: …
6月 12 17:08:17 localhost.localdomain firewalld[15289]: …
6月 12 17:08:17 localhost.localdomain firewalld[15289]: …
Hint: Some lines were ellipsized, use -l to show in full.
状态





