【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]#


相关文章
|
10天前
|
Shell Linux
Linux Shell 脚本入门教程:开启你的自动化之旅
Shell是一种计算机程序,它充当了用户与操作系统之间的接口。在Linux系统中,Shell允许用户通过命令行界面(CLI)来控制计算机。Shell脚本则是一种使用Shell语言编写的脚本,它可以自动执行一系列的命令,帮助用户实现任务自动化,提高工作效率。
|
27天前
|
监控 Shell Linux
Linux的Shell脚本详解
Linux的Shell脚本详解
|
12天前
|
监控 Linux
Linux脚本之监控系统内存使用情况并给予警告
Linux脚本之监控系统内存使用情况并给予警告
|
12天前
|
缓存 网络协议 Linux
Linux下脚本编写局域网扫描工具
Linux下脚本编写局域网扫描工具
|
17天前
|
Linux
Linux每五分钟执行一次某个脚本的定时任务如何写
【6月更文挑战第28天】Linux每五分钟执行一次某个脚本的定时任务如何写
13 0
|
18天前
|
机器学习/深度学习 Unix Java
技术笔记:Linux之Shell脚本编程(一)
技术笔记:Linux之Shell脚本编程(一)
21 0
|
1月前
|
Linux
Linux 系统日常巡检脚本 干货
Linux 系统日常巡检脚本 干货
27 0
|
4天前
|
数据挖掘 Linux 数据处理
Linux命令sprof详解
**`sprof`是Linux下的共享库性能分析工具,补充`gprof`,专注分析`.profile`文件以识别性能瓶颈。通过调用次数、执行时间数据优化资源和代码。使用参数如`-F`、`-I`、`-d`进行定制化分析。示例:先设置`LD_PROFILE`环境变量,运行程序生成`.profile`,然后用`sprof`分析。注意需用`-g`编译程序,并在代表性的负载下分析。结合其他工具如`perf`、`valgrind`提升分析效果。**
|
4天前
|
存储 数据挖掘 Linux
Linux命令split详解:大文件处理的得力助手
`split`命令是Linux用于将大文件分割成小文件的工具,常用于日志处理、备份。它支持按行数(-l)、字节数(-b)分割,并能自定义输出文件名(-a, -d)。例如,`split -b 10M largefile.txt smallfile_`会按10MB切割`largefile.txt`,生成`smallfile_`开头的文件。注意确保磁盘空间充足,避免文件名冲突,并备份原始文件。结合其他命令使用,能提高文件管理效率。
|
1天前
|
关系型数据库 MySQL Linux
Linux命令systemctl详解
`systemctl`是Linux系统用于管理systemd服务的核心命令,它与systemd守护进程交互,实现启动、停止、重启服务及查看服务状态等功能。主要参数包括`start`、`stop`、`restart`、`status`、`enable`和`disable`等。例如,启动Apache服务使用`systemctl start httpd.service`,查看服务状态用`systemctl status &lt;service&gt;`。使用时需注意权限,服务名通常以`.service`结尾,但命令中可省略。最佳实践包括利用tab键补全、定期查看服务状态和合理配置服务自启。