Shell 编程之循环语句

目录

一、for 循环语句

1、for 语句的结构

2、for 语句应用示例

(1)根据姓名列表批量添加用户

(2)根据IP地址列表检查主机状态

二、使用 while 循环语句

1、while 语句的结论

2、while 语句应用示例

(1)批量添加规律编号的用户

(2)猜价格游戏

三、until 循环语句

1、until 语句的结构

2、until 语句应用示例

(1)计算1-50的和


循环语句在Shell编程十分重要,是自动化处理重复任务的利器。

  • for 循环:擅长处理预定义的列表,如批量创建用户账号。
  • while 循环:适用于需要按特定条件重复执行操作的场景。
  • until 循环:与while循环相反,在条件为假时执行循环体。

一、for 循环语句

1、for 语句的结构

使用 for 循环语句时,需要指定一个变量及可能的取值列表,针对每个不同的取值重复执行相同的命令序列,直到变量值用完退出循环。

“取值列表”称为for语句的执行条件,其中包括多个属性相同的对象,需要预先指定(如通讯录、IP黑名单)。

语句结构如下:

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

for语句的操作对象为用户指定名称的变量,并通过 in 关键字为该变量预先设置了一个取值列表,多个取值之间以空格进行分隔。位于 do...done 之间的命令序列称为循环体,其中的执行语句需要引用变量以完成相应的任务。

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

2、for 语句应用示例

(1)根据姓名列表批量添加用户

编辑需要用到的文件

vim /root/users.txt    #用做测试的列表文件
aaa
bbb
ccc
zhangsan
lisi
wangwu
vim uaddfor.sh    #批量添加用户的脚本
#!/bin/bash
ULIST=$(cat /root/users.txt)
for UNAME in $ULIST
do
	useradd $UNAME
	echo "123456" | passwd --stdin $UNAME &>/dev/null
done
chmod +x uaddfor.sh     #给执行权限
./uaddfor.sh     #运行脚本
tail -8 /etc/passwd     #测试并确认执行结果
unbound:x:996:993:Unbound DNS resolver:/etc/unbound:/sbin/nologin
chrony:x:995:992::/var/lib/chrony:/sbin/nologin
aaa:x:1000:1000::/home/aaa:/bin/bash
bbb:x:1001:1001::/home/bbb:/bin/bash
ccc:x:1002:1002::/home/ccc:/bin/bash
zhangsan:x:1003:1003::/home/zhangsan:/bin/bash
lisi:x:1004:1004::/home/lisi:/bin/bash
wangwu:x:1005:1005::/home/wangwu:/bin/bash

若要删除uaddfor.sh脚本所添加的用户,只需参考上面脚本代码,将for循环体中添加用户的命令序列改为删除用户的操作即可。

vim udelfor.sh     #批量删除用户的脚本
#!/bin/bash
ULIST=$(cat /root/users.txt)
for UNAME in $ULIST
do
	userdel -r $UNAME &>/dev/null
done
chmod +x udelfor.sh
tail -3 /etc/passwd     #会发现之前创建的用户都已经没了
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

(2)根据IP地址列表检查主机状态

vim /root/ipadds.txt     #用作测试的列表文件
192.168.10.101
192.168.10.110
127.0.0.1
192.168.20.101
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
chmod +x chkhosts.sh     #给权限
./chkhosts.sh     #测试并确认执行结果
Host 192.168.10.101 is UP
Host 192.168.10.110 is down
Host 127.0.0.1 is UP
Host 192.168.20.101 is down

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

二、使用 while 循环语句

for 循环语句非常适用于列表对象无规律,且列表来源已固定(如某个列表文件)的场合。而对于要求控制循环次数、操作对象按数字顺序编号、按特定条件执行重复操作等情况,则更适合使用另外一种循环——while 语句。

1、while 语句的结论

使用 while 循环语句时,可以根据特定的条件反复执行一个命令序列,直到该条件不再满足时为止。在脚本应用中,应该避免出现死循环的情况,否则后边的命令操作将无法执行。因此,循环体内的命令序列中应包括修改测试条件的语句,以便在适当的时候使测试条件不再成立,从而结束循环。

语法结构如下:

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

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

使用 while 循环语句时,有两个特殊的条件测试操作,即 true(真)和 false(假)。使用 true作为条件时,表示条件永远成立,循环体内的命令序列将无限执行下去,除非强制终止脚本(或通过 exit语句退出脚本);反之,若使用 false 作为条件,则循环体将不会被执行。这两个特殊条件也可以用在 if 语句的条件测试中。

2、while 语句应用示例

(1)批量添加规律编号的用户

vim uaddwhile.sh     #添加用户的脚本
#!/bin/bash
PREFIX="stu"
i=1
while [ $i -le 10 ]
do
        useradd ${PREFIX}$i
        echo "123456" | passwd --stdin ${PREFIX}$i &>/dev/null
        let i++
done

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

chmod +x uaddwhile.sh
./uaddwhile.sh 
grep "stu" /etc/passwd | tail -3
stu8:x:1007:1007::/home/stu8:/bin/bash
stu9:x:1008:1008::/home/stu9:/bin/bash
stu10:x:1009:1009::/home/stu10:/bin/bash

若要删除 uaddwhile.sh 脚本所添加的用户,只需参考上述脚本代码,将 while 循环体中添加用户
的命令序列改为删除用户的操作即可。

vim udelwhile.sh
#!/bin/bash
PREFIX="stu"
i=1
while [ $i -le 10 ]
do
        userdel -r ${PREFIX}$i
        let i++
done
chmod +x udelwhile.sh
./udelwhile.sh         #测试并确认执行结果
cat /etc/passwd     #会发现已经删除了之前创建的用户

(2)猜价格游戏

vim pricegame.sh
#!/bin/bash
PRICE=$(expr $RANDOM % 1000)
TIMES=0
echo "商品实际价格范围为0-999,猜价格是多少?"
while true
do
        read -p "请输入你猜测的价格数目:" INI
        let TIMES++
        if [ $INI -eq $PRICE ]
        then
                echo "恭喜你答对了,实际价格是$PRICE"
                echo "你总共猜测了$TIMES次"
                exit 0
        elif [ $INI -gt $PRICE ]
        then
                echo "太高了!"
        else
                echo "太低了!"
        fi
done
chmod +x pricegame.sh
./pricegame.sh
商品实际价格范围为0-999,猜价格是多少?
请输入你猜测的价格数目:777
太高了!
请输入你猜测的价格数目:444
太高了!
请输入你猜测的价格数目:333
太高了!
请输入你猜测的价格数目:111
太高了!
请输入你猜测的价格数目:77
太高了!
请输入你猜测的价格数目:55
太低了!
请输入你猜测的价格数目:66
太高了!
请输入你猜测的价格数目:50
太低了!
请输入你猜测的价格数目:54
太低了!
请输入你猜测的价格数目:55
太低了!
请输入你猜测的价格数目:56
太低了!
请输入你猜测的价格数目:58
恭喜你答对了,实际价格是58
你总共猜测了12次

三、until 循环语句

1、until 语句的结构

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

语法结构如下:

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

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

2、until 语句应用示例

(1)计算1-50的和

vim sum1to50.sh
#!/bin/bash
i=0;s=0
until [ $i -eq 50 ]
do
	let "i=$i+1";let "s=$s+$i" 
done
	echo 'sum(1..50)=' $s
chmod +x sum1to50.sh 
./sum1to50.sh 
sum(1..50)= 1275

上述代码中,在 i 的值小于 50 之前,每次循环 i 的值加 1,并且求出 s 的值。

你可能感兴趣的:(linux,运维,服务器)