shell脚本编程-循环
shell中的循环主要有for、while、until、select几种
1.列表for循环
for VARIABLE in (list)
do
command
done
执行一定次数的循环(循环次数等于列表元素个数)
1 # cat fruit01.sh 2 #!/bin/bash 3 for FRUIT in apple arange banana pear 4 do 5 echo "$FRUIT is John's favorite" 6 done 7 echo "No more fruits" 8 # sh ./fruit01.sh 9 apple is John's favorite 10 arange is John's favorite 11 banana is John's favorite 12 pear is John's favorite 13 No more fruits
1 root@kali:~/Shell# vim fruit02.sh 2 root@kali:~/Shell# cat fruit02.sh 3 #!/bin/bash 4 fruits="apple oragne banana pear" #将列表定义到一个变量中,以后有任何修改只需要修改变量即可 5 for FRUIT in ${fruits} 6 do 7 echo "$FRUIT is John's favorite" 8 done 9 echo "No more fruits" 10 root@kali:~/Shell# sh ./fruit02.sh 11 apple is John's favorite 12 oragne is John's favorite 13 banana is John's favorite 14 pear is John's favorite 15 No more fruits
如果列表是数字:
1 root@kali:~/Shell# vim for_list01.sh 2 root@kali:~/Shell# cat for_list01.sh 3 #!/bin/bash 4 for VAR in 1 2 3 4 5 5 do 6 echo "Loop $VAR times" 7 done 8 #执行结果 9 root@kali:~/Shell# sh ./for_list01.sh 10 Loop 1 times 11 Loop 2 times 12 Loop 3 times 13 Loop 4 times 14 Loop 5 times
使用{}表示,需相应的shell环境支持
1 root@kali:~/Shell# vim for_list02.sh 2 root@kali:~/Shell# cat for_list02.sh 3 #!/bin/bash 4 for VAR in {1..5} 5 do 6 echo "Loop $VAR times" 7 done 8 root@kali:~/Shell# sh ./for_list02.sh 9 Loop 1 times 10 Loop 2 times 11 Loop 3 times 12 Loop 4 times 13 Loop 5 times
使用seq替换
1 root@kali:~/Shell# cat for_list03.sh 2 #!/bin/bash 3 sum=0 4 for VAR in `seq 1 100` 5 #for VAR in $(seq 1 100) #也用$替换 6 do 7 sum=$(($sum+$VAR)) 8 done 9 #执行结果 10 echo "Total:$sum" 11 root@kali:~/Shell# sh ./for_list03.sh 12 Total:5050
利用seq步长计算1到100内的奇数和
1 root@kali:~/Shell# vim for_list04.sh 2 root@kali:~/Shell# cat for_list04.sh 3 #!/bin/bash 4 sum=0 5 for VAR in $(seq 1 2 100) 6 do 7 sum=$(($sum+$VAR)) 8 done 9 echo "Total $sum" 10 11 root@kali:~/Shell# sh ./for_list04.sh 12 Total 2500
利用ls的输出作为in的列表:
1 root@kali:~/Shell# vim for_list05.sh 2 root@kali:~/Shell# cat for_list05.sh 3 #!/bin/bash 4 for VAR in $(ls) 5 do 6 ls -l $VAR 7 done 8 root@kali:~/Shell# sh ./for_list05.sh 9 -rwxr-xr-x 1 root root 136 9月 24 18:10 chk_file.sh 10 -rwxr-xr-x 1 root root 241 9月 24 18:41 detect_input.sh 11 -rw-r--r-- 1 root root 67 9月 26 11:40 for_list01.sh 12 -rw-r--r-- 1 root root 63 9月 26 11:48 for_list02.sh 13 -rw-r--r-- 1 root root 112 9月 26 12:06 for_list03.sh 14 -rw-r--r-- 1 root root 92 9月 26 12:11 for_list04.sh 15 -rw-r--r-- 1 root root 49 9月 26 12:13 for_list05.sh 16 -rw-r--r-- 1 root root 114 9月 26 11:33 fruit01.sh 17 -rw-r--r-- 1 root root 133 9月 26 11:37 fruit02.sh 18 -rwxr-xr-x 1 root root 318 9月 22 21:46 rwx.sh 19 -rwxr-xr-x 1 root root 197 9月 24 18:04 score01.sh 20 -rwxr-xr-x 1 root root 172 9月 24 18:23 score03.sh 21 -rw-r--r-- 1 root root 0 9月 22 21:46 test
2、不带列表的for循环
for VARIABLE
do
command
done
需要在运行脚本时通过参数的方式给for循环传递变量值
1 root@kali:~/Shell# vim for_list06.sh 2 root@kali:~/Shell# cat ./for_list06.sh 3 #!/bin/bash 4 for VARIABLE 5 do 6 echo -n "$VARIABLE " 7 done 8 echo 9 #执行结果 10 root@kali:~/Shell# sh ./for_list06.sh 1 2 3 4 5 99 11 1 2 3 4 5 99
或通过$@,上面的可读性很差
1 root@kali:~/Shell# vim for_list07.sh 2 root@kali:~/Shell# cat for_list07.sh 3 #!/bin/bash 4 for VARIABLE in $@ 5 do 6 echo -n "$VARIABLE " 7 done 8 #运行时传入参数 9 root@kali:~/Shell# sh ./for_list07.sh 1 8 9 s df 10 1 8 9 s df
3、类C的for循环
需要熟悉C语言,语法:
for ((expressoin1;expression2;expression3))
do
command
done
eg:
1 [rhat@localhost shell]$ vim c_for01.sh 2 [rhat@localhost shell]$ cat c_for01.sh 3 #!/bin/bash 4 for ((i=1;i<=10;i++)) 5 do 6 echo -n "$i " 7 done 8 echo 9 [rhat@localhost shell]$ sh ./c_for01.sh 10 1 2 3 4 5 6 7 8 9 10
循环多个变量
[rhat@localhost shell]$ vim c_for02.sh [rhat@localhost shell]$ cat c_for02.sh #!/bin/bash for ((i=1,j=100;i<=10;i++,j--)) do echo "i=$i j=$j" done echo #执行结果 [rhat@localhost shell]$ sh ./c_for02.sh i=1 j=100 i=2 j=99 i=3 j=98 i=4 j=97 i=5 j=96 i=6 j=95 i=7 j=94 i=8 j=93 i=9 j=92 i=10 j=91
计算1到100以及1到100的奇数和
1 [rhat@localhost shell]$ vim c_for03.sh 2 [rhat@localhost shell]$ cat c_for03.sh 3 #!/bin/bash 4 sum01=0 5 sum02=0 6 for ((i=1,j=1;i<=100;i++,j+=2)) 7 do 8 let "sum01+=i" 9 if [ $j -lt 100 ];then 10 let "sum02+=j" 11 fi 12 done 13 echo "sum01=$sum01" 14 echo "sum02=$sum02" 15 [rhat@localhost shell]$ sh ./c_for03.sh 16 sum01=5050 17 sum02=2500
4、for的无限循环
无限循环特别消耗资源,测试时注意退出条件.
1 [rhat@localhost shell]$ vim c_for04.sh 2 [rhat@localhost shell]$ cat c_for04.sh 3 #!/bin/bash 4 for ((i=0;i<1;i+=0)) 5 do 6 echo "infinite loop" 7 done
1 [rhat@localhost shell]$ vim c_for05.sh 2 [rhat@localhost shell]$ cat c_for05.sh 3 #!/bin/bash 4 for(;1;) 5 do 6 ehco "infinite loop" 7 done
以上代码会一直打印字符,需手动Ctrl+C停止.
语法:
while expression
do
command
done
首先测试expression的返回值,如果返回值为真则执行循环体,否则不执行循环。
1 [rhat@localhost shell]$ vim while01.sh 2 [rhat@localhost shell]$ cat while01.sh 3 #!/bin/bash 4 CONTER=5 5 while [[ $CONTER -gt 0 ]] 6 do 7 echo -n "$CONTER " 8 let "CONTER-=1" #每次循环减少一次CONTER的值 9 done 10 echo 11 [rhat@localhost shell]$ sh ./while01.sh 12 5 4 3 2 1
while:计算1到100的和以及1到100的奇数和
1 [rhat@localhost shell]$ vim while02.sh 2 [rhat@localhost shell]$ cat while02.sh 3 #!/bin/bash 4 sum01=0 5 sum02=0 6 j=1 7 i=1 8 while [[ "$i" -le "100" ]] 9 do 10 let "sum01+=i" 11 let "j=i%2" #变量j用来确定变量i的奇偶性,如果为奇数则j为1 12 if [[ $j -ne 0 ]];then 13 let "sum02+=i" 14 fi 15 let "i+=1" 16 done 17 echo "sum01=$sum01" 18 echo "sum02=$sum02" 19 #执行结果 20 [rhat@localhost shell]$ sh ./while02.sh 21 sum01=5050 22 sum02=2500
while:猜数游戏
1 [rhat@localhost shell]$ vim while03.sh 2 #!/bin/bash 3 PRE_SET_NUM=8 4 echo "Input a number between 1 and 10" 5 while read GUESS 6 do 7 if [[ $GUESS -eq $PRE_SET_NUM ]];then 8 echo "You get the right number" 9 exit 10 else 11 echo "Wrong,try again" 12 fi 13 done 14 echo 15 #执行结果 16 [rhat@localhost shell]$ sh ./while03.sh 17 Input a number between 1 and 10 18 i 19 Wrong,try again 20 1 21 Wrong,try again 22 8 23 You get the right number
while:按行读取文件
例如文件为:
1 [rhat@localhost shell]$ cat student_info.txt 2 John 30 Boy 3 Sue 28 Girl 4 Wang 25 Boy 5 Xu 23 Birl
shell文件:
1 [rhat@localhost shell]$ vim while04.sh 2 #!/bin/bash 3 FNAME=student_info.txt 4 while read LINE #这会产生1个shell,此为重定向 5 #cat $FNAME | while read LINE #或者this,这会产生3个shell,第一个shell为cat,第二个sehll为管道,第三个shell为while 6 do 7 NAME=`echo $LINE | awk '{print $1}'` 8 AGE=`echo $LINE | awk '{print $2}'` 9 Sex=`echo $LINE | awk '{print $3}'` 10 echo "My name is $NAME I'm $AGE years old, I'm a $Sex" 11 done < $FNAME 12 #执行结果 13 [rhat@localhost shell]$ sh ./while04.sh 14 My name is John I'm 30 years old, I'm a Boy 15 My name is Sue I'm 28 years old, I'm a Girl 16 My name is Wang I'm 25 years old, I'm a Boy 17 My name is Xu I'm 23 years old, I'm a Birl
while的无限循环:
语法:3种
while ((1))
do
command
done
----------------------
while true
do
command
done
----------------------
while :
do
command
done
1 [rhat@localhost shell]$ vim while05.sh 2 #!/bin/bash 3 while true 4 do 5 HTTPD_STATUS=`service httpd status | grep runing` 6 if [ -z "$HTTP_STATUS" ]; then 7 echo "HTTPD is stoped,try to restart" 8 service httpd restart 9 else 10 echo "HTTPD is running,wait 5 secuntil next check" 11 fi 12 sleep 5 13 done 14 #执行结果,需要有相应执行权限,否则会报错,Permission deniedLED] 15 [rhat@localhost shell]$ sh ./while05.sh 16 HTTPD is stoped,try to restart 17 ....
until循环也是运行前测试,但是until采用的是测试假值得方式,当测试结果为假时才执行循环体,直到测试为真时才停止循环.语法:
until exprssion
do
command
done
eg:
1 [rhat@localhost shell]$ vim until01.sh 2 #!/bin/bash 3 sum01=0 4 sum02=0 5 i=1 6 until [[ $i -gt 100 ]] 7 do 8 let "sum01+=i" 9 let "j=i%2" 10 if [[ $j -ne 0 ]];then 11 let "sum02+=i" 12 fi 13 let "i+=1" 14 done 15 echo $sum01 16 echo $sum02 17 [rhat@localhost shell]$ sh ./until01.sh 18 5050 19 2500
until无限循环
语法:
until ((0))
do
command
done
------------------------------------------------
until false
do
command
done
select 是一种菜单扩展循环方式,其语法和带列表的for循环类似,语法如下:
select MENU in (list)
do
command
done
1 [rhat@localhost shell]$ vim select01.sh 2 #!/bin/bash 3 echo "Which car do you prefer?" 4 select CAR in Benz Audi VolksWagen 5 do 6 break 7 done 8 echo "You chose $CAR" 9 #执行结果 10 [rhat@localhost shell]$ sh ./select01.sh 11 Which car do you prefer? 12 1) Benz 13 2) Audi 14 3) VolksWagen 15 #? 2 16 You chose Audi
其中带有|的
1 [rhat@localhost shell]$ vim select02.sh 2 #!/bin/bash 3 select DAY in Mon Tue Wed Thu Fri Sat Sun 4 do 5 case $DAY in 6 Mon) echo "Today is Monday";; 7 Tue) echo "Today is Tuesday";; 8 Wed) echo "Today is Wednesday";; 9 Thu) echo "Today is Thursday";; 10 Fri) echo "Today is Friday";; 11 Sat|Sun) echo "You can have a rest today";; 12 *) echo "Unkown input,exit now" && break;; 13 esac 14 done 15 #执行结果 16 [rhat@localhost shell]$ sh ./select02.sh 17 1) Mon 18 2) Tue 19 3) Wed 20 4) Thu 21 5) Fri 22 6) Sat 23 7) Sun 24 #? 1 25 Today is Monday 26 #? 8 27 Unkown input,exit now
for、while、until、select循环语句都可以使用嵌套循环.不建议三层以上的嵌套,否则程序会晦涩难懂.
1 [rhat@localhost shell]$ vim nesting01.sh 2 #!/bin/bash 3 for ((i=1;i<=9;i++)) 4 do 5 for ((j=1;j<=9;j++)) 6 do 7 let "multi=$i*$j" 8 echo -n "$i*$j=$multi " 9 done 10 echo 11 done 12 #执行结果 13 [rhat@localhost shell]$ sh ./nesting01.sh 14 1*1=1 1*2=2 1*3=3 1*4=4 1*5=5 1*6=6 1*7=7 1*8=8 1*9=9 15 2*1=2 2*2=4 2*3=6 2*4=8 2*5=10 2*6=12 2*7=14 2*8=16 2*9=18 16 3*1=3 3*2=6 3*3=9 3*4=12 3*5=15 3*6=18 3*7=21 3*8=24 3*9=27 17 4*1=4 4*2=8 4*3=12 4*4=16 4*5=20 4*6=24 4*7=28 4*8=32 4*9=36 18 5*1=5 5*2=10 5*3=15 5*4=20 5*5=25 5*6=30 5*7=35 5*8=40 5*9=45 19 6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36 6*7=42 6*8=48 6*9=54 20 7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49 7*8=56 7*9=63 21 8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64 8*9=72 22 9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81
or
1 [rhat@localhost shell]$ vim nesting02.sh 2 #!/bin/bash 3 i=1 4 while [[ "$i" -le "9" ]] 5 do 6 j=1 7 while [[ "$j" -le "9" ]] 8 do 9 let "multi=$i*$j" 10 if [[ "$j" -gt "$i" ]];then 11 break 12 else 13 echo -n "$i*$j=$multi " 14 let "j+=1" 15 fi 16 done 17 echo 18 let "i+=1" 19 done 20 #执行结果 21 [rhat@localhost shell]$ sh ./nesting02.sh 22 1*1=1 23 2*1=2 2*2=4 24 3*1=3 3*2=6 3*3=9 25 4*1=4 4*2=8 4*3=12 4*4=16 26 5*1=5 5*2=10 5*3=15 5*4=20 5*5=25 27 6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36 28 7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49 29 8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64 30 9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81
1.break语句
break用于终止当前循环体。一般情况下,break都是和if判断语句一起使用的.
eg:上面改造的99乘法表
2.continue语句
continue语句用于结束当前循环转而进入下一次循环,这和break不同,break是直接终止当前循环,continue是继续下次循环.
eg:打印1到100之间的素数
1 [rhat@localhost shell]$ vim continue02.sh 2 #!/bin/bash 3 for (( i=1;i<=100;i++ )) 4 do 5 for ((j=2;j<i;j++)) 6 do 7 if !(($i%$j));then 8 continue 2 #2代表跳出循环的嵌套数. 9 fi 10 done 11 echo -n "$i " 12 done 13 echo 14 #执行结果 15 [rhat@localhost shell]$ sh ./continue02.sh 16 1 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97