本文中记录一下shell中的两种循环语句:for和while
for循环
for循环是linux shell中最常用的结构,for循环有三种结构:1.列表for循环、2.不带列表for循环、3.C风格的for循环。
1. 列表循环
for var in {list}
do
command
command
...
done
列表循环中,循环执行的次数和list列表中的常数或字符串个数相同,当执行for循环时,首先将list列表中的第一个值赋给循环体作为循环变量,然后执行循环体。接着再赋第二个值,以此类推,直到将list列表中最后一个值赋值执行完后结束整个循环。
示例1:
#!/bin/bash
###
#for i in `seq 1 5` #取值方式与下面一样
for i in {1..5}
do
echo $i
done
列表取值还可以选择步长,例如:
#!/bin/bash
###
sum=0
for i in `seq 1 2 100`
#for i in {1..100..2} #与上面`seq 1 2 100`一样生成1到100,步长为2
do
let sum+=i
done
echo sum:$sum
不带列表循环
不带列表for循环执行时,由用户指定输入参数,shell会自动将命令行输入的所有参数依次组织成列表,每次将一个命令行输入的参数显示给用户,直到所有参数都显示
for var
do
command
command
...
done
示例
#!/bin/bash
###
echo "INPUT of var is: $#"
echo "input is: "
for argument
do
echo $argument
done
#执行
[root@localhost mnt]# ./te-for.sh a b c
INPUT of var is 3
input is:
a
b
c
类C风格的for循环
类C风格的for循环一般被用于循环次数已经知道的情况下;表达式中var1为循环变量赋初值的语句,表达式var2是决定是否进行循环,当判断var2退出状态为0时,执行do和done之间的循环体,当退出状态为非0时,将退出本次循环,执行done后面的语句;表达式var3用于改变循环变量的语句。
示例:
#!/bin/bash
###
sum=0
for (( i=0;i<10;i++ ))
do
let sum+=i
done
echo sum:$sum
while循环
while循环语句也叫测试循环语句,它的循环重复执行次数是利用一个条件来控制是否继续重复执行这个语句的,while语句与for循环语句相比,比较容易懂
while 判断条件
do
command
command
...
done
while之所以命名为前测试循环,是因为它要先判断此循环的条件是否成立,然后才做重复执行操作,也就是说,while循环语句的执行过程是:先判断 ‘添加判断语句’的退出状态,如果退出状态为0,则执行循环体,否则退出执行循环执行done后面的指令,除此之外,while结束循环的方式有两种,一种是 计数控制,一种是 标记匹配控制
- 计数控制
int=1
while (( ${int} <= 5 ))
do
echo $int
let int++
done
#执行
#!/bin/bash
###
int=1
while (( ${int} <= 5 ))
do
echo $int
let int++
done
- 结束标记控制
这种形式是等待用户输入一个参数,当输入的参数与while后的判断语句相等时,就退出整个while循环。如果不等于就等待用户继续输入参数与之对比
read var
while [ $var -ne var2 ]
do
read var
done
示例:猜数字大小
#!/bin/bash
###
read -p "input -a num(1-9) : " num
a=`echo $[RANDOM%10]`
while [ ${num} -ne ${a} ]
do
if [ ${num} -gt ${a} ]; then
echo "To high,try again"
read num
elif [ ${num} -lt ${a} ]; then
echo "Too smaill,try again"
read num
fi
done
echo "good lock"
#执行
[root@localhost mnt]# ./te-for.sh
input -a num(1-9) : 44
To high,try again
2
Too smaill,try again
5
Too smaill,try again
6
Too smaill,try again
7
Too smaill,try again
8
good lock
嵌套循环
一个循环体内又包含另一个完整的循环体,外部循环每次执行都会触发内部循环,当内部所有循环执行完一遍才会执行下一次外部循环
示例:
#!/bin/bash
###
for (( i = 1; i <= 9; i++ ))
do
for (( j=1; j<=i; j++ ))
do
let temp=i*j
echo -n "$i*$j=$temp "
done
echo " "
done
#执行
[root@localhost mnt]# ./te-for.sh
1*1=1
2*1=2 2*2=4
3*1=3 3*2=6 3*3=9
4*1=4 4*2=8 4*3=12 4*4=16
5*1=5 5*2=10 5*3=15 5*4=20 5*5=25
6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36
7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49
8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64
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
循环控制符
有时候需要从循环体重退出循环,退出整个循环或者本次循环,如果是退出整个循环体,则可以使用break,如果是退出本次循环,则可以使用continue
示例:continue
for (( i=1; i<=5; i++ ))
do
if [ $i -eq 3 ]; then
continue
fi
echo $i
done
#执行
[root@localhost mnt]# ./te-for.sh
1
2
4
5
示例:break
for (( i=1; i<=5; i++ ))
do
if [ $i -eq 3 ]; then
break
fi
echo $i
done
#执行
[root@localhost mnt]# ./te-for.sh
1
2
补充内容
外部重定向循环
while还支持从外部文件读取内容
while read line
do
echo $line
done < /file/path
这种方式中while将会一行一行取文件中的内容并将读取的内容定义成变量$line,送到while循环体中进程操作
示例:
#!/bin/bash
#
while read line
do
echo $line
done < /etc/passwd
#执行
[root@localhost mnt]# ./test.sh
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
...省略...
指令重定向
while还可以将指令执行的结果重定向到while循环体中
示例:判断/var目录下的文件类型
#!/bin/bash
find /var -maxdepth 1 | while read line
do
if [ -d $line ];then
echo "$line is dirctory"
elif [ -f $line ]; then
echo "$line is file "
elif [ -L $line ]; then
echo "$line is links "
else
echo "$file is other file type"
fi
done
while死循环
while true; do
循环体
done
示例:循环检查mysqld服务状态,如果down机就启动
#!/bin/bash
sleep 5
while true
do
pgrep mysqld
if [ $? -ne 0 ]; then
service mysqld start
else
echo "mysql server ok"
fi
sleep 5
done