本文共 6063 字,大约阅读时间需要 20 分钟。
shell编程中经常使用`for ; while ; until ; break ; continue等关键字来实现循环语句。
for循环得语法结构:
for var in list //var是变量,for和in是关键字,list是一个变量的集合,循环的每一次都会将list的一个子项赋值给var
do
commands
done
获取list的方法:
直接填入一个列表
示例:编写list_1.sh脚本文件
[root@shell for_do]# bash list_1.sh mounth is Janmounth is Febmounth is Marmounth is Aprmounth is May[root@shell for_do]# cat list_1.sh #!/bin/bashfor var in Jan Feb Mar Apr May //in后面都是列表内容,变量var遍历该列表。do echo "mounth is $var"done
从变量中读取一个列表:
示例:编写list_2.sh脚本文件
[root@shell for_do]# bash list_2.sh mounth is Janmounth is Febmounth is Marmounth is Aprmounth is May[root@shell for_do]# cat list_2.sh #!/bin/bashlist="Jan Feb Mar Apr May" //先定义一个列表,用list变量保存for var in $list //这里直接用list变量do echo "mounth is $var"done
从命令中读取一个列表:
[root@shell for_do]# bash list_3.sh mounth is Janmounth is Febmounth is Marmounth is Aprmounth is May[root@shell for_do]# cat list_3.sh #!/bin/bashfor var in `cat fsx` //这里使用``来执行命令,命令是显示fsx文件内的内容。这里识别一个列表的元素是依靠空格、换行、制表符等分割符实现。修改分割符的方法:IFS=$' \n' 表示只保留换行;表示只能通过换行来分割do echo "mounth is $var"done[root@shell for_do]# cat fsx Jan Feb Mar Apr May
IFS:修改分割符
示例:
[root@shell for_do]# bash list_ifs.sh mounth is Jan Feb Mar Apr May[root@shell for_do]# cat list_ifs.sh #!/bin/bashIFS=$';'list="Jan Feb Mar Apr May"for var in $listdo echo "mounth is $var"done
这时,分割符只能用“ ; ”来分割。所以上面识别变量只有一个元素,要分开必须使用" ; ",如下:
[root@shell for_do]# bash list_ifs.sh mounth is Janmounth is Febmounth is Marmounth is Aprmounth is May[root@shell for_do]# cat list_ifs.sh #!/bin/bashIFS=$';'list="Jan;Feb;Mar;Apr;May"for var in $listdo echo "mounth is $var"done
从目录读取一个列表:
与前三种不同,for
循环支持读取一个目录,将目录内容作为循环列表进行使用。
示例:
[root@shell for_do]# bash list_4.sh /mnt/for_do[root@shell for_do]# cat list_4.sh #!/bin/bashfor var in /mnt/for_dodo echo "$var"done//上面的形式时错误的,因为这样,内核不识别/mnt/for_do为一个目录,认为它是一个字符串,所以,要让内核识别为一个目录,要使用文件的通配符号 * ,即:/mnt/for_do/*。//这里面的通配符使用和使用`ls`命令时使用的一样[root@shell for_do]# bash list_4.sh /mnt/for_do/fsx/mnt/for_do/list_1.sh/mnt/for_do/list_2.sh/mnt/for_do/list_3.sh/mnt/for_do/list_4.sh/mnt/for_do/list_ifs.sh[root@shell for_do]# cat list_4.sh #!/bin/bashfor var in /mnt/for_do/* //此处使用了通配符 * ;所以上面可以输出/mnt/for_do/ 下的所有文件名do echo "$var"done
第二种for
循环使用结构:
for ((i=1;i<10;i++)) //注意这里是双括号
do
commands
done
示例:
[root@shell for_do]# bash list_5.sh test number is 0 99test number is 1 98test number is 2 97test number is 3 96test number is 4 95[root@shell for_do]# cat list_5.sh #!/bin/bashfor((i=0,j=99;i<5;i++,j--))do echo "test number is $i $j"done//shell中for循环判断条件支持多个变量,用逗号隔开
while和until十分相似,这里对比着进行解释。
while的基本语法结构:
while test command //test测试command是否执行成功
do
commands
done
while:直到后面条件成功时,才进入循环
until的基本语法结构:
until test command
do
commands
done
until:直到后面条件成功时,才退出循环
while示例:
[root@shell while_until]# bash test_1.sh 1234[root@shell while_until]# cat test_1.sh #!/bin/bashvar=1while [ $var -lt 5 ] //test可以用[]代替,即当var变量的值小于5时,进入循环。'-lt'是小于do echo "$var" var=$[ $var+1 ] //var变量值每次加1,是expr命令,可以用[]代替done
unti示例:
[root@shell while_until]# bash test_2.sh 1234[root@shell while_until]# cat test_2.sh #!/bin/bashvar=1until [ $var -eq 5 ] //当变量等于5时,循环才退出do echo "$var" var=$[ $var+1 ]done
如果条天永远不成立,会变成死循环
基于for循环的基本语法,可以在里面继续嵌套。
示例:
[root@shell while_until]# bash test_3.sh test number i is 0test number j is 1test number j is 2test number i is 1test number j is 1test number j is 2test number i is 2test number j is 1test number j is 2test number i is 3test number j is 1test number j is 2test number i is 4test number j is 1test number j is 2[root@shell while_until]# cat test_3.sh #!/bin/bashfor (( i=0;i<5;i++))do echo "test number i is $i" for ((j=1;j<3;j++)) do echo "test number j is $j" donedone
while嵌套也一样:
[root@shell while_until]# bash test_4.sh test number i is 0test number j is 1test number j is 2test number i is 1test number j is 1test number j is 2test number i is 2test number j is 1test number j is 2test number i is 3test number j is 1test number j is 2test number i is 4test number j is 1test number j is 2[root@shell while_until]# cat test_4.sh #!/bin/bashi=0while [ $i -lt 5 ]do echo "test number i is $i" for (( j=1;j<3;j++)) do echo "test number j is $j" done i=$[ $i + 1 ] done
我们可以使用break和continue来实现指定环境下的循环控制。
break示例:
[root@shell while_until]# bash test_5.sh test number is 1test number is 2[root@shell while_until]# cat test_5.sh #!/bin/bashfor (( i=1;i<5;i++))do if [ $i -eq 3 ] then break; fi echo "test number is $i"done//当for循环执行到i=3时,进入循环,但是if判断到,i变量等于3,进入if语句,break直接跳出循环,所以不再执行其他。
continue示例:
[root@shell while_until]# bash test_6.sh test number is 1test number is 2test number is 4[root@shell while_until]# cat test_6.sh #!/bin/bashfor (( i=1;i<5;i++))do if [ $i -eq 3 ] then continue; fi echo "test number is $i"done//当遇到continue,就不在继续执行当前一步骤的循环,而直接进入下一个步骤的循环。对于本示例就是,当i等于3,执行if语句,遇到continue,就不再执行echo命令,而直接进行下一个循环的i自增,和判断是否for循环条件成立
一个稍微复杂的例子:
通过循环和条件判断,输出指定用户名的/ect/passwd
的配置:
先每行遍历循环,定义变量row,表示每行变量内容;因为每行为一个元素,所以分割符为" \n ",即换行符号
在嵌套一个循环,在每行内进行遍历,定义变量value,表示每行中得单个元素,因为以" ; "间隔,所以分割符为" ; "
在对某一行进行遍历的时候,我们知道其中第一个元素时用户名;即遍历的是第一个元素,且(&&)该元素名==输入的用户名,则匹配到。
匹配到,得有一个标识记录,这里用is_target记录(为0表示没有匹配到,为1表示匹配到)
if判断,如果is_target=1,则输出row变量信息,跳出循环。
[root@shell while_until]# cat test_7.sh #!/bin/bashecho "please input a user name"read unameIFS=$'\n'for row in `cat /etc/passwd`do IFS=$':' i=1 is_target=0 for value in $row do if [ $i -eq 1 ] && [ $value = $uname ] then is_target=1 fi i=$[ $i + 1 ] done if [ $is_target -eq 1 ] then echo $row break; fidone
测试结果:
[root@shell while_until]# bash test_7.sh please input a user namerootroot x 0 0 root /root /bin/bash[root@shell while_until]# bash test_7.sh please input a user namefsxfsx x 500 500 /home/fsx /bin/bash[root@shell while_until]# bash test_7.sh please input a user namenobodynobody x 99 99 Nobody / /sbin/nologin
总结:综合运用了条件判断,和循环使用
转载地址:http://dqhxd.baihongyu.com/