shell编程之循环语句

目录

for循环语句

1,for语句的结构

2,for语句应用示例

while循环语句

1,while语句的结构

2,while语句应用示例

until循环语句

1,until循环语句结构

2,until循环语句应用示例

循环语句,作为自动化处理重复任务的利器,在 She11 编程中扮演着至关重要的角色。for 循环、while循环以及 unti1 循环,循环语句是 She11 编程中的核心要素。它不仅能够简化脚本的编写过程,还能提升脚本的执行效率和可维护性。掌握并熟练运用这个工具,将为您的Shel1编程之旅增添无限可能。主要分为以下三类

for循环:for 循环擅长处理预定义的列表,如批量创建用户账号。

while循环:while 循环则更适用于需要按特定条件重复执行操作的场景。

until循环:until循环则与 while 循环相反,在条件为假时执行循环体。

for循环语句

1,for语句的结构

使用 for 循环语句时,需要指定一个变量及可能的取值列表,针对每个不同的取值重复执行相同的命令序列,直到变量值用完退出循环。在这里,“取值列表”称为for 语句的执行条件,其中包括多个属性相同的对象,需要预先指定(如通讯录、IP黑名单),for循环语句的语法结构如下:

for 变量名 in 取值列表
do
  命令序列
done

for 语句的执行流程:首先将列表中的第一个取值赋给变量,并执行 do.done 循环体中的命令序列;然后将列表中的第二个取值赋给变量,并执行循环体中的命令序列…依此类推,直到列表中的所有取值用完,最后将跳至 done 语句,表示结束循环。

shell编程之循环语句_第1张图片

2,for语句应用示例

  • 根据姓名列表批量添加用户

在inux 服务器中批量添加相应的用户账号,初始密码均设置为“123456”。其中,员工姓名列表中的账号数量并不固定,而且除了要求账号名称是拼音之外,并无其他特殊规律。

编写一个名为user.txt的员工列表文件,里面存储要创建的账号名字

[root@localhost opt]# cat /user.txt       
zhangsan
lisi
wangwu
zhaoliu

编写一个名为for.sh的shell脚本,从user.txt文件中读取各用户名称,重复执行添加用户,设置初始密码的相关操作。

[root@localhost opt]# cat for.sh           
#!/bin/bash
add=`cat /user.txt`
for UNAME in $add
do
	useradd $UNAME
	echo "123456" | passwd --stdin $UNAME &>/dev/null      ##初始密码设置为123456
done

[root@localhost opt]# chmod +x for.sh

验证测试结果

[root@localhost opt]# bash for.sh


[root@localhost opt]# tail -4 /etc/passwd      ##查看用户信息后4行
zhangsan:x:1000:1000::/home/zhangsan:/bin/bash
lisi:x:1001:1001::/home/lisi:/bin/bash
wangwu:x:1002:1002::/home/wangwu:/bin/bash
zhaoliu:x:1003:1003::/home/zhaoliu:/bin/bash

如果要删除创建的用户也可以使用脚本来执行

[root@localhost opt]# cat fordel.sh
#!/bin/bash
add=`cat /user.txt`
for UNAME in $add
do
        userdel -r $UNAME &>/dev/null       ##只需将useradd更改为userdel -r 
done


[root@localhost opt]# chmod +x fordel.sh 

验证脚本编写结果

[root@localhost opt]# bash fordel.sh
  
[root@localhost opt]# tail -4 /etc/passwd    ##再次查看发现已被删除
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
unbound:x:996:993:Unbound DNS resolver:/etc/unbound:/sbin/nologin
chrony:x:995:992::/var/lib/chrony:/sbin/nologin
  • 根据ip地址列表检查主机状态

检査其中各主机的 ping 连通性,输出各主机是否启动、关闭。其中,服务器的数量并不固定,各服务器的IP地址之间也无特殊规律,可先指定 IP 地址列表文件 ip.txt。然后编写一个名为 ping.sh的Shel1 脚本,从 ip.txt 文件中读取各服务器的 IP 地址,重复执行 ping 连通性测试,并根据测试结果输出相应的提示信息。

[root@localhost opt]# cat /ip.txt   ##编写ip地址测试的列表文件
192.168.10.102
172.16.16.1
192.168.10.111
172.16.16.220
127.0.0.1

编写名为ping.sh的脚本

[root@localhost opt]# cat ping.sh
#!/bin/bash
ping=$(cat /ip.txt)
for ip in $ping
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 ip down."
fi
done

[root@localhost opt]# chmod +x ping.sh

对ping.sh脚本进行测试

[root@localhost opt]# bash ping.sh
Host 192.168.10.102 is up.
Host 172.16.16.1 ip down.
Host 192.168.10.111 ip down.
Host 172.16.16.220 ip down.
Host 127.0.0.1 is up.

do…done循环体内嵌套使用了 if 条件选择语句,用来针对不同 P 地址的测试结果进行判断,并输出相应的提示信息。嵌套可以理解为镶嵌、套用,就是在已有的语句、函数中在多加一个或多个语句、函数等。实际上,if 语句、for 语句及其他各种 She11 脚本语句都是可以嵌套使用的,后续课程中将不再重复说明。

  • 检查指定网段的主机状态
[root@localhost /]# cat a.sh
for i in {1..254}
do
	ping -c 2 -i 0.3 -W 1 192.168.10.$i &>/dev/null
    #每隔0.3秒ping一次,一共ping2次,并以1毫秒为单位设置ping的超时时间
	if [ $? -eq 0 ];
	then
		echo "192.168.10.$i is up"
	else
		echo "192.168.10.$i is down"
	fi
done

[root@localhost /]# chmod +x a.sh

  • 9*9乘法表
[root@localhost /]# cat d.sh
for i in `seq 9`
do
  	for j in `seq $i`
   	do
       	echo -n "$j*$i=$[i*j]  "
   	done
    echo
done


[root@localhost /]#chmod +x d.sh

[root@localhost /]# . d.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循环语句时,可以根据特定的条件反复执行一个命令序列,直到该条件不再满足时为止。在脚本应用中,应该避免出现死循环的情况,否则后边的命令操作将无法执行。因此,循环体内的命令序列中应包括修改测试条件的语句,以便在适当的时候使测试条件不再成立,从而结束循环,格式如下:

while 条件测试操作
do
   命令序列
done

while 语句的执行流程:首先判断 while 后的条件测试操作结果,如果条件成立,则执行 do..done循环体中的命令序列;返回 while 后再次判断条件测试结果,如果条件仍然成立,则继续执行循环体:再次返回到 while 后,判断条件测试结果!……如此循环,直到 while 后的条件测试结果不再成立为止,最后跳转到 done 语句,表示结束循环。

shell编程之循环语句_第2张图片

2,while语句应用示例

  • 批量添加规律编号的用户

如果需要批量添加用户账号,这些用户名称中包含固定的前缀字串,按照数字顺序依次进行编号,账号数量往往也是固定的,例如 添加10个用户,名称为name1,name2......name10。

[root@localhost opt]# cat while.sh 
#!/bin/bash
while="name"
i=1
while [ $i -le 10 ]
do 
	useradd ${while}$i
	echo "123456" | passwd --stdin ${while}$i &>/dev/null
	let i++
done

[root@localhost opt]# chmod +x while.sh 

使用变量 i 来控制用户名称的编号,初始赋值为 1,并且当取值大于 10 时终止循环。在循环体内部,通过语句“let i++”(等同于 i=`expr $i +1`)来使变量 i 的值增加 1,因此当执行第一次循环后 i 的值将变为 2,执行第二次循环后 i 的值将变为 3,…,依此类推。

[root@localhost opt]# cat /etc/passwd | grep name
name1:x:1000:1000::/home/name1:/bin/bash
name2:x:1001:1001::/home/name2:/bin/bash
name3:x:1002:1002::/home/name3:/bin/bash
name4:x:1003:1003::/home/name4:/bin/bash
name5:x:1004:1004::/home/name5:/bin/bash
name6:x:1005:1005::/home/name6:/bin/bash
name7:x:1006:1006::/home/name7:/bin/bash
name8:x:1007:1007::/home/name8:/bin/bash
name9:x:1008:1008::/home/name9:/bin/bash
name10:x:1009:1009::/home/name10:/bin/bash

如果想要删除脚本创建的用户,只需要修改以下部分。


[root@localhost opt]# cat whiledel.sh 
#!/bin/bash
while="name"
i=1     
while [ $i -le 10 ]
do
    userdel -r ${while}$i &>/dev/null         ##将useradd改为userdel -r
	let i++
done  

[root@localhost opt]# chmod +x whiledel.sh 

查看删除的结果

[root@localhost opt]# tail -5 /etc/passwd          ##发现没有关于name的用户
dhcpd:x:177:177:DHCP server:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
unbound:x:996:993:Unbound DNS resolver:/etc/unbound:/sbin/nologin
chrony:x:995:992::/var/lib/chrony:/sbin/nologin


  • 猜价格游戏脚本

针对上述要求,主要设计思路如下:通过环境变量 RANDOM 可获得一个小于 216的随机整数,计算其与 1000 的余数即可获得 ~999 的随机价格;反复猜测操作可以通过以 true 作为测试条件的while 循环实现,当用户猜中实际价格时终止循环;判断猜测价格与实际价格的过程采用 if 语句实现,嵌套在 while 循环体内;使用变量来记录猜测次数。

[root@localhost opt]# cat while2.sh 
#!/bin/bash
PRICE=$(expr $RANDOM % 1000)
TIMES=0
echo "商品价格范围0-999,请输入一个价格猜猜看"
while true
do
	read -p "请输入你猜测的价格数目:" INT
	let TIMES++
	if [ $INT -eq $PRICE ]
	then
		echo "恭喜你答对了,实际价格是$PRICE"
		echo "你总共猜测了$TIMES次"
		exit 0
	elif [ $INT -gt $PRICE ]
	then
		echo "太高了"
	else
		echo "太低了"
	fi
done

[root@localhost opt]# chmod +x while2.sh

 

测试while2.sh脚本的执行结果

[root@localhost opt]# bash while2.sh
商品价格范围0-999,请输入一个价格猜猜看
请输入你猜测的价格数目:500
太高了
请输入你猜测的价格数目:300
太低了
请输入你猜测的价格数目:400
太高了
请输入你猜测的价格数目:350
太低了
请输入你猜测的价格数目:360
太高了
请输入你猜测的价格数目:355
太高了
请输入你猜测的价格数目:3354
太高了
请输入你猜测的价格数目:354
太高了
请输入你猜测的价格数目:353
太高了
请输入你猜测的价格数目:352
太高了
请输入你猜测的价格数目:351
恭喜你答对了,实际价格是351
你总共猜测了11次

until循环语句

1,until循环语句结构

unti1 循环与 while 循环类似,while 循环能实现的脚本 unti1 同样也可以实现,但区别是while循环在条件为真是继续执行循环,而 unti1 则是在条件为假时执行循环,格式如下:

until 条件测试操作
do
  命令序列
done

unti1 语句的执行流程: 首先判断 unti1 后的条件测试操作结果,如果条件不成立,则执行 do..done循环体中的命令序列;返回 unti1 后再次判断条件测试结果,如果条件仍然不成立,则继续执行循环体;再次返回到 unti1 后,判断条件测试结果.…如此循环,直到 unti1 后的条件测试结果成立为止,最后跳转到 done 语句,表示结束循环。

shell编程之循环语句_第3张图片

2,until循环语句应用示例

  • 计算1-50的和

计算从 1 到58 的和,从1开始相加,采用循环的方式,每次循环后加 1,将得到的值加入计算的和中,数字运算采用的是 let 方式,直到加到 50 为止.。

[root@localhost opt]# cat until.sh
#!/bin/bash
i=0;s=0
until [ $i -eq 50 ]
do
	let "i=$i+1";let "s=$s+$i"      ##在i的值小于50之前,每次循环i的值加1,并且求出s的值
done
echo 'sum(1..50)=' $s

[root@localhost opt]# chmod +x until.sh



[root@localhost opt]# bash until.sh            ##验证脚本编写结果
sum(1..50)= 1275
  • 为指定用户发送在线消息
[root@localhost opt]# cat until2.sh
#!/bin/bash
#检查参数数量是否足够
if [ $# -lt 2 ]; then
    echo "Usage: $0  ..."
    exit 1
fi

#提取消息,消息为最后一个参数
message="${$#}"

#遍历除最后一个参数外的所有用户名
for username in "${@:1:$#-1}"; do

#检查用户是否为系统内用户
if ! grep -q "^$username:" /etc/passwd; then
echo "$username is not a valid user on this system."
continue
fi

#持续检查用户是否登陆
while ! who | grep -q "$username"; do
echo "$username is not logged on. Waiting for the user to log in..."
sleep 60
done

#用户已登陆,发送信息
echo "Sending message to $username..."
write "$username" <

对刚刚编写的until2.sh脚本进行测试

[root@localhost opt]# bash until2.sh root hello 
发送给root自己,消息为hello


[root@localhost opt]# bash until2.sh zhangsan hello
发送给zhangsan用户,消息为hello

你可能感兴趣的:(github,linux,运维)