for循环
- 语法:
for 变量名 in 条件; do …; done - 案例1:
[root@second ~]# seq 3 #队列不指定开始值和步长;
1
2
3
[root@second ~]# seq 2 3 #指定开始值;
2
3
[root@second ~]# seq 1 2 10 #指定开始值与步长;
1
3
5
7
9
[root@second ~]# seq 2 2 10 #指定开始值与步长;
2
4
6
8
10
#! /bin/bash
sum=0
for i in `seq 1 5` #i变量值在1-5里循环;
do #循环里操作开始;
echo $i
sum=$(($sum+$i))
done #操作结束;
echo $sum
[root@second ~]# bash for.sh #运行结果;
1
2
3
4
5
15
- 案例2
#! /bin/bash
cd /root/
for i in `ls` #将逐个文件名的值赋给i,进行循环;
do
if [ -d $i ]
then
ls -ld $i
fi
done
[root@second ~]# bash !$ #运行结果;
bash for2.sh
drwxr-xr-x 2 root root 6 11月 19 15:14 dir1
drwxr-xr-x. 5 root root 4096 11月 16 17:24 linux2019
drwxr-xr-x. 3 root root 20 11月 17 10:23 rstest
while 循环
-
语法
while 条件; do … ; done -
案例1
分步尝试1:
[root@second ~]# w
10:37:16 up 1 day, 8:09, 1 user, load average: 0.10, 0.08, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
user1 pts/0 192.168.87.1 二15 4.00s 1.98s 0.38s sshd: user1 [priv]
[root@second ~]# w |head -1
10:37:29 up 1 day, 8:09, 1 user, load average: 0.09, 0.07, 0.05
[root@second ~]# w |head -1 |awk -F "load average: " '{print $2}'
0.12, 0.08, 0.05
[root@second ~]# w |head -1 |awk -F "load average: " '{print $2}'|cut -d "." -f 1
0
[root@second ~]# w |head -1 |awk -F "load average: " '{print $2}'|awk -F "." '{print $1}'
0
分步尝试2:
[root@second ~]# echo "kkk" |mail -s "load" ***@163.com #顺便安装一下邮件功能;
[root@second ~]# echo $?
0
收到邮件
while脚本
#! /bin/bash
while :
do
i=`w |head -1 |awk -F "load average: " '{print $2}'|awk -F "." '{print $1}'`
if [ $i -eq 0 ] #应该改成 $i -ge 10, 负载大时执行;
then
top -bn1 | mail -s "over load" ***@163.com
fi
sleep 10 #可以加到30秒;
done
运行结果:
[root@second ~]# bash -x while.sh #执行过程,收到两封邮件;
+ :
++ w
++ head -1
++ awk -F 'load average: ' '{print $2}'
++ awk -F . '{print $1}'
+ i=0
+ '[' 0 -eq 0 ']'
+ top -bn1
+ mail -s 'over load' ***@163.com
+ sleep 10
+ :
++ head -1
++ awk -F 'load average: ' '{print $2}'
++ awk -F . '{print $1}'
++ w
+ i=0
+ '[' 0 -eq 0 ']'
+ mail -s 'over load' ***@163.com
+ top -bn1
+ sleep 10
^C
- 案例2
输入数字才能结束的脚本:
#! /bin/bash
while :
do
read -p "please input a number:" n
if [ -z "$n" ] #为空时,提示与continue;
then
echo "you need to input sth."
continue #重头开始,do后面的语句;
fi
m=`echo $n |sed s/[0-9]//g`
if [ ! -z "$m" ] #输入含数字外的字符,提示与continue;
then
echo "numbers only."
continue
fi
echo $n
break #跳出循环;
done
运行结果
[root@second ~]# bash while2.sh
please input a number:
you need to input sth.
please input a number:dd
numbers only.
please input a number:ii9
numbers only.
please input a number:99
99
break跳出循环
- 跳出一个循环
参考标准
#! /bin/bash
for i in `seq 1 5`
do
echo $i
if [ $i -eq 3 ]
then
echo "run to the if, one more low for 3"
fi
done
运行结果:
[root@second ~]# bash break.sh
1
2
3
run to the if, one more low for 3
4
5
使用break后
#! /bin/bash
for i in `seq 1 5`
do
echo $i
if [ $i -eq 3 ]
then
echo "run to the if, one more low for 3"
break #跳出循环,所以没有echo 4 5;
fi
done
运行结果:
[root@second ~]# bash break.sh
1
2
3
run to the if, one more low for 3
- 两个循环中的break
参考标准
#! /bin/bash
for j in `seq 1 2`
do
echo $j
for i in `seq 1 5`
do
echo $i
if [ $i -eq 3 ]
then
echo "run to the if, one more low for 3"
fi
done
done
运行结果:
[root@second ~]# bash break.sh
1 #第一次j循环;
1
2
3
run to the if, one more low for 3
4
5
2 #第二次j循环;
1
2
3
run to the if, one more low for 3
4
5
使用break后
#! /bin/bash
for j in `seq 1 2`
do
echo $j
for i in `seq 1 5`
do
echo $i
if [ $i -eq 3 ]
then
echo "run to the if, one more low for 3"
break
fi
done
done
运行结果:
[root@second ~]# bash break.sh
1
1
2
3
run to the if, one more low for 3 #跳出i的循环,但是j的循环还在继续;
2
1
2
3
run to the if, one more low for 3 #运行到同样的位置,中止;
continue跳出循环
一个循环中使用:
#! /bin/bash
for i in `seq 1 5`
do
echo $i
if [ $i -eq 3 ]
then
continue #跳出一个循环,跳过了下面语句,可对比上面参考标准的运行结果;
echo "run to the if, one more low for 3"
fi
done
运行结果:
[root@second ~]# bash continue.sh
1
2
3
4
5
二个循环中使用,跟break同样只跳出一个循环
#! /bin/bash
for j in `seq 1 2`
do
echo $j
for i in `seq 1 5`
do
echo $i
if [ $i -eq 3 ]
then
continue
echo "run to the if, one more low for 3"
fi
done
done
运行结果:
[root@second ~]# bash !$
bash continue2.sh
1
1
2
3
4
5
2
1
2
3
4
5
exit退出整个脚本
运行到exit整个脚本退出
#! /bin/bash
for j in `seq 1 2`
do
echo $j
for i in `seq 1 5`
do
echo $i
if [ $i -eq 3 ]
then
echo "run to the if, one more low for 3"
exit 2 #exit并定义返回值;
fi
done
done
[root@second ~]# bash exit.sh
1
1
2
3
run to the if, one more low for 3
[root@second ~]# echo $? #定义exit返回值,可以检查运行出现问题的地方;
2
- 注意
[root@second ~]# for line in `cat /etc/passwd` #逐段输入;
> do
> echo $line
> echo "##"
> done
部分结果:
rpcuser:x:29:29:RPC #文件中含空格的行会变成两部分输出,跟逐行输出的想法不一致;
##
Service
##
User:/var/lib/nfs:/sbin/nologin
##
可以用以下方式解决:
[root@second ~]# cat /etc/passwd | while read line ; do echo $line ; echo "##"; done #实现了逐行输出;
root:x:0:0:root:/root:/bin/bash
##
bin:x:1:1:bin:/bin:/sbin/nologin
##
体会read的意义:
[root@second ~]# echo -e "567\tkkkk"| while read line ; do echo $line ; echo "##"; done #标准输入的一行都可以补read捕获;
567 kkkk
##
[root@second ~]# echo -e "567\nkkkk"| while read line ; do echo $line ; echo "##"; done #如果换行了,代表输入两次,while循环两次;
567
##
kkkk
##
另外一个方法,实现逐行输出:
#! /bin/bash
for i in `seq 1 100`;
do
echo $i
m=`sed -n "$i"p /etc/passwd`;
echo $m
if [ -z "$m" ]; #如果没有双引号,输出就不正常, 空格让这句语句不正常,一般提示太多参数;
then
break;
fi
done
[root@second ~]# for i in `seq 1 100`; do m=`sed -n "$i"p /etc/passwd`; if [ -z "$m" ]; then break; fi;echo $m; done #改成一行语句;