Shell 脚本应用(三)
一、for 循环语句
1.for 语句的结构
2.使用 for 语句创建脚本
1)批量添加用户
2)根据 IP 地址检查主机状态
3)99 乘法表
二、while 循环语句
1.while 语句的结构
2.使用 while 语句创建脚本
1)批量添加用户
2)猜商品价格游戏
3)IP 和 MAC 地址采集脚本
三、case 多分支语句
1.case 语句的结构
2.使用 case 语句创建脚本
1)检查用户输入的字符类型
2)根据文件扩展名自动选择相应的解压选项
3)Apache 服务启动脚本
一、for 循环语句
1.for 语句的结构
- 读取不同的变量值,用来逐个执行同一组命令。
for 变量名 in 取值列表 do 命令序列 done
取值列表有多种取值方式,比如:可以直接读取 in 后面的值,默认以空格做分隔。
2.使用 for 语句创建脚本
1)批量添加用户
1.将用户名存放在 1.txt 文件中,每行一个
[root@localhost ~]# vim 1.txt zhangsan lisi wangwu xiaoming
2.创建 for 循环语句脚本
[root@localhost ~]# vim 1.sh #!/bin/bash for a in `cat /root/1.txt` # 从列表文件读取用户名 do useradd $a &>/dev/null # 通过管道指定密码字串 echo "123" | passwd --stdin $a &>/dev/null done
3.执行脚本
[root@localhost ~]# chmod +x 1.sh [root@localhost ~]# ./1.sh [root@localhost ~]# tail -4 /etc/passwd zhangsan:x:1001:1001::/home/zhangsan:/bin/bash lisi:x:1002:1002::/home/lisi:/bin/bash wangwu:x:1003:1003::/home/wangwu:/bin/bash xiaoming:x:1004:1004::/home/xiaoming:/bin/bash
2)根据 IP 地址检查主机状态
1.将IP 地址存放在 2.txt 文件中,每行一个
[root@localhost ~]# vim 2.txt 192.168.1.1 192.168.1.2 192.168.1.3
2.创建 for 循环语句脚本
[root@localhost ~]# vim 2.sh #!/bin/bash for A in $(cat /root/2.txt) do ping -c 3 -i 0.2 -W 3 $A &> /dev/null if [ $? -eq 0 ] # 嵌套 if 语句判断连通性 then echo "Host $A is Up" else echo "Host $A is Down" fi done
3.执行脚本
[root@localhost ~]# chmod +x 2.sh [root@localhost ~]# ./2.sh Host 192.168.1.1 is Up #因为宿主机的 IP 地址是 1.1. 所以可以通信 Host 192.168.1.2 is Down Host 192.168.1.3 is Down
3)99 乘法表
[root@localhost ~]# vim 99.sh #!/bin/bash for A in {1..9} do for B in {1..9} do if [ $A -ge $B ] then # echo -e:表示支持反斜线控制的字符转换 # echo -n:表示输出结果后不换行 # \t:表示制表符. 让形式看起来更美观 echo -ne "$B*$A=$[$A*$B]\t" fi done echo "" done [root@localhost ~]# sh 99.sh 1*1=1 1*2=2 2*2=4 1*3=3 2*3=6 3*3=9 1*4=4 2*4=8 3*4=12 4*4=16 1*5=5 2*5=10 3*5=15 4*5=20 5*5=25 1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36 1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49 1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64 1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
二、while 循环语句
1.while 语句的结构
- 重复测试某个条件,只要条件成立则反复执行;
- while 语句有两个特殊的条件测试操作,true 真和 false 假,只有当条件测试为 true 时,才会执行命令序列。
while 条件测试操作 do 命令序列 done
2.使用 while 语句创建脚本
1)批量添加用户
[root@localhost ~]# vim 3.sh #!/bin/bash name="zhangsan" A=1 while [ $A -le 20 ] # 循环条件:序号 <=20 do useradd ${name}$A &>/dev/null echo "123" | passwd --stdin ${name}$A &>/dev/null let A++ # 序号递增. 避免死循环 done [root@localhost ~]# cat /etc/passwd | tail -20 zhangsan1:x:1003:1003::/home/zhangsan1:/bin/bash zhangsan2:x:1004:1004::/home/zhangsan2:/bin/bash zhangsan3:x:1005:1005::/home/zhangsan3:/bin/bash zhangsan4:x:1006:1006::/home/zhangsan4:/bin/bash zhangsan5:x:1007:1007::/home/zhangsan5:/bin/bash zhangsan6:x:1008:1008::/home/zhangsan6:/bin/bash zhangsan7:x:1009:1009::/home/zhangsan7:/bin/bash zhangsan8:x:1010:1010::/home/zhangsan8:/bin/bash zhangsan9:x:1011:1011::/home/zhangsan9:/bin/bash zhangsan10:x:1012:1012::/home/zhangsan10:/bin/bash zhangsan11:x:1013:1013::/home/zhangsan11:/bin/bash zhangsan12:x:1014:1014::/home/zhangsan12:/bin/bash zhangsan13:x:1015:1015::/home/zhangsan13:/bin/bash zhangsan14:x:1016:1016::/home/zhangsan14:/bin/bash zhangsan15:x:1017:1017::/home/zhangsan15:/bin/bash zhangsan16:x:1018:1018::/home/zhangsan16:/bin/bash zhangsan17:x:1019:1019::/home/zhangsan17:/bin/bash zhangsan18:x:1020:1020::/home/zhangsan18:/bin/bash zhangsan19:x:1021:1021::/home/zhangsan19:/bin/bash zhangsan20:x:1022:1022::/home/zhangsan20:/bin/bash
2)猜商品价格游戏
- 通过变量 RANDOM 获得随机数,提示用户猜测并记录次数,猜中后退出循环。
[root@localhost ~]# vim 4.sh #!/bin/bash A=$(expr $RANDOM % 100) B=0 echo "商品实际价格为 0-99 之间. 猜猜看是多少?" while true # 循环条件:true (真) do read -p "请输入你认为的价格:" C let B++ if [ $C -eq $A ];then # 提示猜测并记录次数 echo "恭喜你. 猜对了" echo "你总共猜了 $i 次" exit 0 # 若猜中退出脚本 elif [ $C -gt $A ];then # 与实际价格比较. 给出提示 echo "太高了" else echo "太低了" fi done [root@localhost ~]# chmod +x 4.sh [root@localhost ~]# ./4.sh 商品实际价格为 0-99 之间. 猜猜看是多少? 请输入你认为的价格:50 太高了 请输入你认为的价格:30 太高了 请输入你认为的价格:20 太低了 请输入你认为的价格:23 恭喜你. 猜对了 你总共猜了 4 次
3)IP 和 MAC 地址采集脚本
- 使用 arping 命令获取反馈的 MAC 地址;使用 while 循环查询一个 IP 网段的所有 IP 和 MAC 地址。
- 格式:arping -I 网络接口 目标IP
[root@localhost ~]# vim getarp.sh #!/bin/bash A=248 read -p "例:192.168.1. 请输入你要搜索的网段:" NET while [ $A -le 251 ] # 只要 $A 变量值小于或等于 251 就执行以下: do ping -c 1 $NET$A &>/dev/null # 测试连通性. 并混合输出到黑洞里 if [ $? -eq 0 ];then # 查看上条命令是否正确. 正确 = 0. 将执行以下命令 #筛选出能够通信的IP和MAC地址 IP=$(arping -I ens32 -c 1 $NET$A | grep "reply" | awk '{print $4}') # 设置 IP 变量 MAC=$(arping -I ens32 -c 1 $NET$A | grep "reply" | awk '{print $5}' | awk -F] '{print $1}' | awk -F[ '{print $2}') # 设置 MAC 变量 echo "$IP $MAC" > /opt/address.txt fi # 结束 if 语句 let A++ # 每当执行一次 $A 变量. 都会加1. 直到不满足为止 done # 结束循环
[root@localhost ~]# chmod +x getarp.sh # 添加可执行权限 [root@localhost ~]# ./getarp.sh # 执行脚本 [root@localhost ~]# cat /opt/address.txt # 查看输出文件
三、case 多分支语句
1.case 语句的结构
- 它是根据变量的不同进行取值比较,然后针对不同的取值分别执行不同的命令操作。
- 适用于多分支,是一个多分支语句。
case 变量值 in 模式1) 命令序列1 ;; 模式2) 命令序列2 ;; …… * ) 默认命令序列 ;; esac
case 语句执行流程控制:
- case 的行尾必须为单词 in,每一个模式都要以右括号 ) 结束。
- 双分号 ;; 表示命令序列结束。
- 模式字符串中,可以用方括号表示一个连续的范围,如 [0-9] ;还可以用竖杠符号 | 表示或,如 A|B 。
- *):表示默认模式,其中的 * 相当于通配符。
case 语句支持通配符:
- *:任意长度字符。
- ?:任意单个字符。
- []:指定范围内的任意单个字符。
2.使用 case 语句创建脚本
1)检查用户输入的字符类型
- 提示用户输入一个字符,判断出该字符是字母、数字或者其他字符。
[root@localhost ~]# vim 5.sh #!/bin/bash read -p "请输入一个字符,并按Enter键确认:" A case $A in [0-9]) # 匹配数字 0-9 echo "你输入的是数字" ;; [a-z]|[A-Z]) # 匹配小写或大写字母 echo "你输入的是字母" ;; *) echo "你输入的是空格、功能键或其他控制字符" ;; esac
执行该脚本
[root@localhost ~]# chmod +x 5.sh [root@localhost ~]# sh 5.sh 请输入一个字符,并按Enter键确认:6 你输入的是数字 [root@localhost ~]# sh 5.sh 请输入一个字符,并按Enter键确认:y 你输入的是字母 [root@localhost ~]# sh 5.sh 请输入一个字符,并按Enter键确认:@ 你输入的是空格、功能键或其他控制字符
2)根据文件扩展名自动选择相应的解压选项
判断 *.tar.gz *.tar.bz2
[root@localhost ~]# mkdir /opt/gz /opt/bz2 # 创建两个目录用来做测试用 [root@localhost ~]# ll /opt/gz/ /opt/bz2/ # 查看两个目录 将两个文件压缩成gz格式: [root@localhost ~]# tar zcf user.tar.gz /etc/passwd /etc/shadow 将两个文件压缩成bz2格式: [root@localhost ~]# tar jcf user.tar.bz2 /etc/passwd /etc/shadow [root@localhost ~]# vim znjy.sh # 编写解压脚本 #!/bin/bash #此脚本根据文件扩展名自动选择相应的解压选项 case "$1" in *.tar.gz) tar zxf $1 -C /opt/gz &>/dev/null ;; *.tar.bz2) tar jxf $1 -C /opt/bz2 &>/dev/null ;; *) echo "只能解决gz和bz2方式的压缩文件" ;; esac [root@localhost ~]# ll # 查看
[root@localhost ~]# chmod +x znjy.sh # 添加可执行权限 [root@localhost ~]# ./znjy.sh user.tar.gz # 解压 gz 格式压缩文件 [root@localhost ~]# ll /opt/gz/ /opt/bz2/ # 以长格式查看 [root@localhost ~]# ./znjy.sh user.tar.bz2 # 解压 bz2 格式压缩文件 [root@localhost ~]# ll /opt/gz/ /opt/bz2/ # 以长格式查看 [root@localhost ~]# ./znjy.sh aaa # 解压 aaa
3)Apache 服务启动脚本
[root@localhost ~]# yum -y install httpd [root@localhost ~]# vim fuwu.sh #!/bin/bash case $1 in start) systemctl $1 httpd echo "httpd服务已启用" ;; stop) systemctl $1 httpd echo "httpd服务已关闭" ;; restart) systemctl $1 httpd echo "服务已重启" ;; status) netstat -anpt | grep httpd &>/dev/null if [ $? -eq 0 ] then echo "httpd监听端口:$(netstat -anpt | grep httpd | awk '{print $4}')" else echo "httpd未启用" fi;; *) echo "只能使用,start,stop,restart,status参数" esac
执行该脚本
[root@localhost ~]# chmod +x fuwu.sh [root@localhost ~]# ./fuwu.sh start httpd服务已启用 [root@localhost ~]# ./fuwu.sh stop httpd服务已关闭 [root@localhost ~]# ./fuwu.sh restart 服务已重启 [root@localhost ~]# ./fuwu.sh status httpd监听端口::::80 [root@localhost ~]# ./fuwu.sh aaa 只能使用,start,stop,restart,status参数