shell脚本应用(三)for、while、case语句

前言:当面对各种列表重复任务时,使用if语句已经难以满足要求,而顺序编写全部代码更是显得异常繁琐,困难重重。使用循环、分支等其他程序控制结构,从而能够轻松完成更加复杂、强大的功能。
1、使用for循环语句
for语句结构:
for 变量名 in 取值列表
do
命令序列
done
for循环语句的结构:

1)根据姓名列表批量添加用户
准备员工列表文件users.txt,然后编写一个名为uaddfor.sh的脚本,从users.txt文件中读取各用户名称,重复执行添加用户,设置初始密码的相关操作。
[root@localhost ~]# vim /root/user.txt //用作测试的列表文件
chenpeng
dengchao
zhangjie
批量添加用户的脚本
[root@localhost ~]# vim uaddfor.sh
#!/bin/bash
ulist=$(cat /root/user.txt)
for uname in $ulist
do
useradd $uname
echo "123456" | passwd --stdin $uname &> /dev/null
done
[root@localhost ~]# chmod +x uaddfor.sh //添加执行权限
[root@localhost ~]# ./uaddfor.sh //测试并确认执行结果
[root@localhost ~]# tail -3 /etc/passwd
chenpeng:x:501:501::/home/chenpeng:/bin/bash
dengchao:x:502:502::/home/dengchao:/bin/bash
zhangjie:x:503:503::/home/zhangjie:/bin/bash
2)若要删除uaddfor.sh脚本添加的用户,只需要将上面脚本中添加用户的命令改为删除的即可。
[root@localhost ~]# cp uaddfor.sh udelfor.sh
[root@localhost ~]# vim udelfor.sh //批量删除用户的脚本
#!/bin/bash
ulist=$(cat /root/user.txt)
for uname in $ulist
do
userdel $uname
echo "123456" | passwd --stdin $uname &> /dev/null
done
[root@localhost ~]# chmod +x udelfor.sh
[root@localhost ~]# ./udelfor.sh
[root@localhost ~]# id chenpeng
id: chenpeng:无此用户
执行脚本之后发现用户已经删除
3)根据ip地址列表查看主机状态
首先建立ip地址列表文件ipadds.txt,然后编写一个名为chkhosts.sh的shell脚本,从ipadds.txt文件中读取各服务器的ip地址,重复执行ping连通性测试,并根据测试结果输出相应的提示信息。
[root@localhost ~]# vim /root/ipadds.txt //用作测试的列表文件
192.168.1.1
192.168.1.2
192.168.1.10
[root@localhost ~]# vim /chkhosts.sh //循环检查各主机的脚本
#!/bin/bash
hlist=$(cat /root/ipadds.txt)
for ip in $hlist
do
ping -c 3 -i 0.2 -W 3 $ip &> /dev/null
if [ $? -eq 0 ]
then
echo "host $ip is up"
else
echo "host $ip is down"
fi
done
执行脚本
[root@localhost /]# chmod +x chkhosts.sh
[root@localhost /]# ./chkhosts.sh
host 192.168.1.1 is up
host 192.168.1.2 is down
host 192.168.1.10 is down
2、使用while循环语句
For循环适合无规律,列表已固定,while循环适合要求循环次数,操作对象按数字顺序编号,按特定条件执行重复操作的情况。
while语句的语法结构:
while 条件测试操作
do
命令序列
done
while循环语句的结构:

1)批量添加规律编号的用户,添加20个用户,名称依次为stu1,stu2,... Stu20
[root@localhost /]# vim uaddwhile.sh
#!/bin/bash
prefix="stu"
i=1
while [ $i -le 20 ]
do
useradd ${prefix}$i
echo "123456" | passwd --stdin ${prefix}$i &> /dev/null
let i++
done
[root@localhost /]# chmod +x uaddwhile.sh
[root@localhost /]# ./uaddwhile.sh
[root@localhost /]# grep "stu" /etc/passwd | tail -3
stu18:x:518:518::/home/stu18:/bin/bash
stu19:x:519:519::/home/stu19:/bin/bash
stu20:x:520:520::/home/stu20:/bin/bash
2)删除所添加的用户,只需将上述代码useradd修改成userdel即可
[root@localhost /]# cp uaddwhile.sh udelwhile.sh
[root@localhost /]# vim udelwhile.sh
#!/bin/bash
prefix="stu"
i=1
while [ $i -le 20 ]
do
userdel ${prefix}$i
echo "123456" | passwd --stdin ${prefix}$i &> /dev/null
let i++
done
[root@localhost /]# chmod +x udelwhile.sh
[root@localhost /]# ./udelwhile.sh
[root@localhost /]# id stu20
id: stu20:无此用户
3)猜价格游戏
案例要求如下:由脚本预先生成一个随机的价格数目(0~999)作为实际价格,判断用户猜测的价格是否高出或低出实际价格,给出相应的提示够再次要求用户猜测;一直到用户猜中实际价格为止,输出用户共猜测的次数、实际价格。
思路:通过环境变量RANDOM可获得一个小于2的16次方的随机整数,计算其与1000的余数即可获得0-999的随机价格,反复猜测操作可以通过以true作为测试条件的while循环实现,当用户猜中实际价格时终止循环,判断猜测价格与实际价格的过程采用if语句实现,嵌套在while循环体内,使用变量来记录猜测次数。
[root@localhost /]# vim pricegame.sh
#!/bin/bash
price=$(expr $RANDOM % 1000)
TIMES=0
echo "shangpin 0-999,ni cai?"
while true
do
read -p "qing shu ru:" INT
let TIMES++
if [ $INT -eq $price ] ; then
echo "gongxi, jiageshi:$price"
echo "ni cai le $TIMES ci"
exit 0
elif [ $INT -gt $price ] ; then
echo "taigaole"
else
echo "taidile"
fi
done
[root@localhost /]# chmod +x pricegame.sh
[root@localhost /]# ./pricegame.sh
shangpin 0-999,ni cai?
qing shu ru:500
taigaole
qing shu ru:400
taidile
qing shu ru:450
taidile
qing shu ru:470
taigaole
qing shu ru:469
taigaole
qing shu ru:460
gongxi, jiageshi:460
ni cai le 6 ci
3、使用case分支语句
Case语句可以使用脚本程序的结构更加清晰。与if语句非常相似,只不过if语句需要判断多个不同的条件,而case语句只是判断一个变量的不同取值。
case分支语句的语法结构:
case 变量值 in
模式1)
命令序列1
;;
模式2)
命令序列2
;;
......................

默认命令序列
esac
(
是通配符,可匹配任意值)
case分支语句的结构:

使用case分支语句时,需要注意:
1,case行尾必须为单词“in”,每一模式必须以右括号“)”结束
2,双分号“;;”表示命令序列的结束
3,模式字符串中,可以用方括号表示一个连续的范围,如【0-9】;还可以用竖杠符号“|”表示或,如“A|B”
4,最后的“)”表示默认模式,其中的相当于通配符
1)检查用户输入一个字符,通过case语句判断该字符是否为字母,数组或其他控制字符,并给出相应的提示信息。
[root@localhost /]# vim hitkey.sh
#!/bin/bash
read -p "qingshuru:" KEY
case "$KEY" in
[a-z] | [A-Z])
echo "ni shu ru de shi zimu"
;;
[0-9])
echo "ni shu ru de shi shuzi"
;;
)
echo "ni shu ru de shi qita"
esac
[root@localhost /]# chmod +x hitkey.sh
[root@localhost /]# ./hitkey.sh
qingshuru:z
ni shu ru de shi zimu
[root@localhost /]# ./hitkey.sh
qingshuru:7
ni shu ru de shi shuzi
[root@localhost /]# ./hitkey.sh
qingshuru: /
ni shu ru de shi qita
2)编写系统服务脚本
通过位置变量$1指定的start,stop,restart,status控制参数,分别用来启动、停止、重启sleep进程,以及查看sleep进程的状态。
[root@localhost /]# vim myprog
#!/bin/bash
#chkconfig - 90 10
#description:aaaaaaaaaa
case "$1" in
start)
echo -n "zhengzaiqidong sleep fuwu..."
if sleep 7200 & //在后台启动sleep进程
then
echo "ok"
fi
;;
stop)
echo -n "zhengzaitingzhi sleep fuwu"
pkill "sleep" &> /dev/null //杀死sleep进程
echo "ok"
;;
status)
if pgrep "sleep" &> /dev/null ; then //判断并提示sleep进程状态
echo "sleep fuwu yiqidong"
else
echo "sleep fuwu yitingzhi"
fi
;;
restart) //先停止,再启动服务
$0 stop
$0 start
;;
) //默认显示用法信息
echo "yongfa: $0 {start|stop|status|restart}"
esac
[root@localhost /]# chmod +x myprog
[root@localhost /]# ./myprog start
zhengzaiqidong sleep fuwu...ok
[root@localhost /]# ./myprog status
sleep fuwu yiqidong
[root@localhost /]# ./myprog stop
zhengzaitingzhi sleep fuwuok
[root@localhost /]# ./myprog reload //未提供此参数,按默认处理
yongfa: ./myprog {start|stop|status|restart}

然后执行下面的命令添加myprog为系统服务
[root@localhost /]# cp myprog /etc/init.d/

转载于:https://blog.51cto.com/13557682/2067232

你可能感兴趣的:(shell脚本应用(三)for、while、case语句)