【Linux脚本篇】循环语句-for

简介: 【Linux脚本篇】循环语句-for

       前面讲的判断语句if和case只能做判断,可以说只能做一些判断。如果判断结果为假,将执行最后的命令(一般是exit退出脚本),如果不想退出,继续选从零开始小于10以内的次数,择正确的选项,就需要继续回到上面选择,这时就需要循环语句。循环语句可以做类似于一级菜单、二级菜单的选项,直到选择正确的选项,最后可以退出脚本,这就是一个完整的程序。循环语句有for和while两种,本章讲解的是for语句。

for的语法格式

1. for 变量名 in [取值列表]
2. do
3.     循环命令语句
4. done

       语法格式上来看,还是很简单的,我们在来几个简单的案例,让我们更加理解。

for循环案例

案例一:循环创建文件

       目的是在根下filedir目录创建100个文件;在执行前先确定有没有该目录,所以就需要用到判断语句,如果没有这个目录则创建,有则不执行,

1. [root@daxia sh]# vim for1.sh 
2. #!/bin/bash
3. 
4. text=/filedir
5. 
6. [ ! -d $text ] && mkdir $text
7. 
8. for I in {1..100}
9. do
10.        touch ${text}/hehe$I
11. done
12. 
13. [root@daxia sh]# sh for1.sh 
14. [root@daxia sh]# ls /filedir/

案例二:应用引号或转义符

       for循环的取值比较复杂,我们可以使用引号或转义符。比如说下面的file1需要用单引号引起来,但是如果不使用转义符,系统会以为引起来的内容是一起的,不会打印出来单引号。而后面的hello beijing不用引号引起来,系统会以为是两个值,分开打印。

1. [root@daxia sh]# vim for2.sh 
2. #!/bin/bash
3. for F in \'file1\' "hello beijing" file4 "hello world"
4. do
5.        echo the text is $F
6. done
7. [root@daxia sh]# sh for2.sh 
8. the text is 'file1'
9. the text is hello beijing
10. the text is file4
11. the text is hello world

案例三:从变量中取值

在循环里,取值列表可以是变量,先定一个变量,里面添加值,在for里面引用。

1. [root@daxia sh]# vim for3.sh
2. #!/bin/bash
3. List="file1 file2 file3"
4. for I in $List
5. do
6.        echo "the text is ${I}"
7. done
8. [root@daxia sh]# sh for3.sh
9. the text is file1
10. the text is file2
11. the text is file3

案例四:从命令中取值

在命令中取值默认以空格为分隔符,可以使用IFS自定义分隔符。

1. [root@daxia sh]# vim for4.sh
2. #!/bin/bash
3. for H in $(cat /etc/hosts)
4. do
5.        echo "$H"
6. done
7. [root@daxia sh]# sh for4.sh
8. 127.0.0.1
9. localhost
10. localhost.localdomain
11. localhost4
12. localhost4.localdomain4
13. ::1
14. localhost
15. localhost.localdomain
16. localhost6
17. localhost6.localdomain6

#以冒号做分隔符 IFS=: #以分号做分隔符 IFS=";" #以换行符做字段分隔符 IFS=$'\n'

       我们可以看到上面,执行后,原本两行的文本,打印出了很多行。这就很不合理,我们后面把分隔符改成换行作为分隔符。

1. [root@daxia sh]# vim for4.sh
2. #!/bin/bash
3. 
4. IFS=$'\n'
5. for H in $(cat /etc/hosts)
6. do
7.        echo "$H"
8. done
9. [root@daxia sh]# sh for4.sh 
10. 127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
11. ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

案例五:for循环自增自减

       我们来感受下自增的变化吧,根据上面几个案例,我们可以在值中写入多个用户,然后再循环创建。但是如果使用自增的话可以指定创建多少,并且不用写那么多的值。下面for语句中的i=1表示初始值为1,i<=10则是表示最多等于10或小于10,i++则是每次循环加一。这样我们就可以创建出十个不同数字的用户了,试想一下,自增还能给我们带来哪些便利呢?

1. [root@daxia sh]# vim for5.sh
2. #!/bin/bash
3. for (( i=1;i<=10;i++ ))
4. do
5.         useradd sc$i
6. done
7. [root@daxia sh]# sh for5.sh 
8. [root@daxia sh]# tail -10 /etc/passwd
9. sc1:x:1000:1000::/home/sc1:/bin/bash
10. sc2:x:1001:1001::/home/sc2:/bin/bash
11. sc3:x:1002:1002::/home/sc3:/bin/bash
12. sc4:x:1003:1003::/home/sc4:/bin/bash
13. sc5:x:1004:1004::/home/sc5:/bin/bash
14. sc6:x:1005:1005::/home/sc6:/bin/bash
15. sc7:x:1006:1006::/home/sc7:/bin/bash
16. sc8:x:1007:1007::/home/sc8:/bin/bash
17. sc9:x:1008:1008::/home/sc9:/bin/bash
18. sc10:x:1009:1009::/home/sc10:/bin/bash

同时输出1-9的升序和降序,注意:多个值之间是用逗号分隔,结束用分号分隔。

1. [root@daxia sh]# vim for5_1.sh
2. #!/bin/bash
3. for (( a=1,b=9;a<=10;a++,b-- ))
4. do
5.        echo "num is $a $b"
6. done
7. [root@daxia sh]# sh for5_1.sh 
8. num is 1 9
9. num is 2 8
10. num is 3 7
11. num is 4 6
12. num is 5 5
13. num is 6 4
14. num is 7 3
15. num is 8 2
16. num is 9 1
17. num is 10 0

用另外一种方式来实现升序和降序

1. [root@daxia sh]# vim for5_2.sh
2. #!/bin/bash
3. a=0
4. b=10
5. for i in {1..9}
6. do
7. let a++
8. let b--
9. echo "num is $a $b"
10. done
11. [root@daxia sh]# sh for5_2.sh 
12. num is 1 9
13. num is 2 8
14. num is 3 7
15. num is 4 6
16. num is 5 5
17. num is 6 4
18. num is 7 3
19. num is 8 2
20. num is 9 1

案例六:批量创建用户

       我们先看看RANDOM随机数生成命令,100表示最大生成的随机数,然后+1表示从1开始,如果不+1则随机数可能是0。

[root@daxia sh]# echo $((RANDOM % 100 + 1))

这次脚本写一个批量创建用户,提示用户输入前缀、数量,指定root用户才能执行脚本,密码随机(使用RANDOM命令),前缀不能为空。

1. [root@daxia sh]# vim for6.sh 
2. #!/bin/bash
3. if [ ! $UID -eq 0 ] && [ $USER != "root" ];then
4. echo "你不是管理员,执行失败"
5. exit
6. fi
7. read -p "请输入你的用户前缀:" User_a
8. if [ -z $User_a ];then
9. echo "请输入有效的前缀"
10. exit
11. fi
12. read -p "请输入你的用户数量:" User_b
13. if [[ ! $User_b =~ ^[0-9]+$ ]];then
14. echo "请输入整数"
15. exit
16. fi
17. 
18. read -p "是否创建用户【y|n】:" yn
19. case $yn in
20.         y)
21. for i in $(seq $User_b)
22. do
23.                         user=${User_a}$i
24. id $user &> /dev/null
25. if [ $? -eq 0 ];then
26. echo "useradd:user $user already exists"
27. else
28.                                 user_pass=$(echo $((RANDOM)) | md5sum | cut -c 2-10 )
29.                                 useradd $user
30. echo "$user_pass" | passwd --stdin $user &> /dev/null
31. echo "用户:$user 密码:$user_pass " >> /tmp/user.txt
32. echo "useradd:user $user add successfull,密码在/tmp/user.txt"
33. fi
34. done
35.                 ;;
36.         n)
37. exit
38.                 ;;
39.         *)
40. echo "error:请输入【y|n】:"
41. esac
42. 
43. [root@daxia sh]# sh for6.sh
44. 请输入你的用户前缀:zhang
45. 请输入你的用户数量:3
46. 是否创建用户【y|n】:y
47. useradd:user zhang1 add successfull,密码在/tmp/user.txt
48. useradd:user zhang2 add successfull,密码在/tmp/user.txt
49. useradd:user zhang3 add successfull,密码在/tmp/user.txt
50. [root@daxia sh]# cat /tmp/user.txt 
51. 用户:zhang1 密码:29a106702 
52. 用户:zhang2 密码:6ded89b39 
53. 用户:zhang3 密码:b984e2b01

       自行测试吧,切换用户测试非root用户(非0用户),执行脚本测试是否执行。然后修改脚本成批量删除用户,测试是否成功。

案例七:批量探测主机

       批量检查主机(以8.0网段为例),并检查主机22端口是否开启。检查22端口需要使用nmap命令,需要提前安装。为了节省时间,这里就扫描三台主机了。

1. [root@daxia sh]# vim for7.sh
2. #!/bin/bash
3. for i in {100..102}
4. do
5.         Ip=192.168.8.$i
6.         ping -c 1 -w 1 $Ip &> /dev/null
7. if [ $? -eq 0 ];then
8. echo "$Ip is ok"
9. echo "$Ip" >> /tmp/ip.log
10. else
11. echo "$Ip is down"
12. fi
13. done
14. wait
15. echo "scan host ip is done"
16. echo "scan ssh port is starting"
17. 
18. for i in $(cat /tmp/ip.log)
19. do
20.         nmap $i |grep "22" &> /dev/null
21. 
22. if [ $? -eq 0 ];then
23. echo "$i 22端口已开启"
24. echo "$i 22端口已开启" >> /tmp/port.log
25. fi
26. done
27. 
28. [root@daxia sh]# sh for7.sh 
29. 192.168.8.100 is ok
30. 192.168.8.101 is down
31. 192.168.8.102 is down
32. scan host ip is done
33. scan ssh port is starting
34. 192.168.8.100 22端口已开启
35. 192.168.8.100 22端口已开启
36. 192.168.8.100 22端口已开启

案例八:随机点名

       在一个文档中写入人名,通过过滤筛选出一个。先用wc命令过滤出student.txt中有几个人,来决定循环几次。在通过随机数计算出第几位,并使用sed命令确定人名,循环外面则是计算出的人名高亮显示。

1. [root@daxia sh]# cat student.txt 
2. 张三
3. 李四
4. 王五
5. 马六
6. 朱七
7. [root@daxia sh]# vim for8.sh
8. #!/bin/bash
9. num=$(wc -l student.txt|awk '{print $1}')
10. for i in {1..$num}
11. do
12.   stu_num=$(( RANDOM % $num + 1 ))
13.   sed -n "${stu_num}p" student.txt
14.   sleep 0.1
15. done
16.   name_stu=$(sed -n "${stu_num}p" student.txt)
17.   echo -e "就是你了:\033[32m $name_stu \033[0m"
18. 
19. [root@daxia sh]# sh for8.sh
20. 李四
21. 就是你了: 李四 
22. [root@daxia sh]# sh for8.sh
23. 朱七
24. 就是你了: 朱七 
25. 案例九:随机猜数字
26. 
27. [root@daxia sh]# vim for9.sh
28. #!/bin/bash
29. num=$(echo $(( RANDOM % 100 )))
30. 
31. i=0
32. while true
33. do
34.        read -p "请输入一个随机数字【1-100】:" sz
35.        if [[ ! $sz =~ ^[0-9]+$ ]];then
36.                echo "请输入有效的整数"
37.                continue
38.        fi
39. 
40.        if [ $sz -gt $num ];then
41.                echo "你的数字过大"
42.        elif [ $sz -lt $num ];then
43.                echo "你的数字过小"
44.        else
45.                echo "恭喜,你猜对了!!!"
46.                break
47.        fi
48.        let i++
49. done
50.        echo "你总共猜了 $(( $i + 1 )) 次。"
51. [root@daxia sh]# sh for9.sh
52. 请输入一个随机数字【1-100】:50
53. 你的数字过小
54. 请输入一个随机数字【1-100】:80
55. 你的数字过大
56. 请输入一个随机数字【1-100】:70
57. 你的数字过大
58. 请输入一个随机数字【1-100】:60
59. 你的数字过小
60. 请输入一个随机数字【1-100】:65
61. 你的数字过大
62. 请输入一个随机数字【1-100】:63
63. 你的数字过大
64. 请输入一个随机数字【1-100】:62
65. 你的数字过大
66. 请输入一个随机数字【1-100】:61
67. 恭喜,你猜对了!!!
68. 你总共猜了 8 次。
69. [root@daxia sh]#


相关文章
|
2月前
|
存储 安全 Unix
七、Linux Shell 与脚本基础
别再一遍遍地敲重复的命令了,把它们写进Shell脚本,就能一键搞定。脚本本质上就是个存着一堆命令的文本文件,但要让它“活”起来,有几个关键点:文件开头最好用#!/usr/bin/env bash来指定解释器,并用chmod +x给它执行权限。执行时也有讲究:./script.sh是在一个新“房间”(子Shell)里跑,不影响你;而source script.sh是在当前“房间”里跑,适合用来加载环境变量和配置文件。
402 9
|
Ubuntu Linux 网络安全
Linux系统初始化脚本
一款支持Rocky、CentOS、Ubuntu、Debian、openEuler等主流Linux发行版的系统初始化Shell脚本,涵盖网络配置、主机名设置、镜像源更换、安全加固等多项功能,适配单/双网卡环境,支持UEFI引导,提供多版本下载与持续更新。
272 0
Linux系统初始化脚本
|
2月前
|
存储 Shell Linux
八、Linux Shell 脚本:变量与字符串
Shell脚本里的变量就像一个个贴着标签的“箱子”。装东西(赋值)时,=两边千万不能有空格。用单引号''装进去的东西会原封不动,用双引号""则会让里面的$变量先“变身”再装箱。默认箱子只能在当前“房间”(Shell进程)用,想让隔壁房间(子进程)也能看到,就得给箱子盖个export的“出口”戳。此外,Shell还自带了$?(上条命令的成绩单)和$1(别人递进来的第一个包裹)等许多特殊箱子,非常有用。
284 2
|
4月前
|
Web App开发 缓存 安全
Linux一键清理系统垃圾:释放30GB空间的Shell脚本实战​
这篇博客介绍了一个实用的Linux系统盘清理脚本,主要功能包括: 安全权限检查和旧内核清理,保留当前使用内核 7天以上日志文件清理和系统日志压缩 浏览器缓存(Chrome/Firefox)、APT缓存、临时文件清理 智能清理Snap旧版本和Docker无用数据 提供磁盘空间使用前后对比和大文件查找功能 脚本采用交互式设计确保安全性,适合定期维护开发环境、服务器和个人电脑。文章详细解析了脚本的关键功能代码,并给出了使用建议。完整脚本已开源,用户可根据需求自定义调整清理策略。
498 1
|
6月前
|
Java Linux
自定义linux脚本用于快速jar包启动、停止、重启
自定义linux脚本用于快速jar包启动、停止、重启
319 29
|
6月前
|
Linux Shell
Centos或Linux编写一键式Shell脚本删除用户、组指导手册
Centos或Linux编写一键式Shell脚本删除用户、组指导手册
190 4
|
6月前
|
Linux Shell 数据安全/隐私保护
Centos或Linux编写一键式Shell脚本创建用户、组、目录分配权限指导手册
Centos或Linux编写一键式Shell脚本创建用户、组、目录分配权限指导手册
385 3
|
监控 Linux
linux服务器显卡监控脚本
linux服务器显卡监控脚本
263 0
|
监控 Shell Linux
Linux 性能监控之CPU&内存&I/O监控Shell脚本1
Linux 性能监控之CPU&内存&I/O监控Shell脚本1
374 0