一、当型循环和直到型循环
当型循环结构:在每次执行循环体前,对条件进行判断,当条件满足时,执行循环体,否则终止循环。
直到型循环结构:在执行了一次循环体后,对条件进行判断,如果条件不满,就继续执行,知道条件满足终止循环。
Shell编程中循环命令用于特定条件下决定某些语句重复执行的控制方式,
有三种常用的循环语句:for、while和until。
while循环和for循环属于“当型循环”,而until属于“直到型循环”。
循环控制符:break和continue控制流程转向。
while 结构:
while循环语句也称前测试循环语句,它的循环重复执行次数,是利用一个条件来控制是否继续重复执行这个语句。
while语句与for循环语句相比,无论是语法还是执行的流程,都比较简明易懂。while循环格式如下:
while 条件
do
command
command
…
done
while循环语句之所以命名为前测试循环,是因为它要先判断此循环的条件是否成立,然后才作重复执行的操作。也
就是说,while循环语句执行过程是:先判断expression的退出状态,如果退出状态为0,则执行循环体,并且在执
行完循环体后,进行下一次循环,否则退出循环执行done后的命令。
为了避免死循环,必须保证在循环体中包含循环出口条件,即存在expression的退出状态为非0的情况。
until(感觉和while相反)
先做,知道条件不满足才退出
until[condition-is-true]
do
command..
done
应用场合不多,了解就好
二、实例
每隔两秒记录一次系统负载情况
sleep 1 休息1秒,usleep 1000000休息一秒
[root@node01 day11]# vi while01.sh
#!/bin/sh
while true
do
uptime
sleep 2
done
[root@node01 day11]# sh while01.sh
13:46:06 up 5 days, 14:09, 4 users, load average: 0.00, 0.00, 0.00
13:46:08 up 5 days, 14:09, 4 users, load average: 0.00, 0.00, 0.00
13:46:10 up 5 days, 14:09, 4 users, load average: 0.00, 0.00, 0.00
while true表示条件永远为真,因此会一直运行,像死循环一样,但是我们称呼为守护进程。
[root@node01 day11]# vi while01.sh
#!/bin/sh
while [ 1 ]
do
uptime >>./uptime.log
usleep 1000000
done
[root@node01 day11]# sh while02.sh
[root@node01 day11]# ls
uptime.log while01.sh while02.sh
[root@node01 day11]# cat uptime.log
14:00:26 up 5 days, 14:23, 4 users, load average: 0.00, 0.00, 0.00
14:00:27 up 5 days, 14:23, 4 users, load average: 0.00, 0.00, 0.00
如果使用&会在后台永久执行,这就是守护进程。
[root@node01 day11]# vi while01.sh 这个放后台运行也会前台打印,所以加入到log文件
#!/bin/sh
while true
do
uptime >>/var/log/uptime.log
sleep 2
done
防止脚本执行中断的方法
1、sh while.sh &
2、screen (保持会话)
3、nohup uptime.sh &
[root@node01 day11]# sh while01.sh 当已经执行了,但是没有放后台,又不想终止,先敲ctrl+z暂停
^Z
[1]+ Stopped sh while01.sh
[root@node01 day11]# bg 然后敲bg放入后台执行(fg放到前台)
[1]+ sh while01.sh &
[root@node01 day11]# sh while01.sh
^Z
[2]+ Stopped sh while01.sh
[root@node01 day11]# bg
[2]+ sh while01.sh &
[root@node01 day11]# jobs 列出job
[1]- Running sh while01.sh &
[2]+ Running sh while01.sh &
[root@node01 day11]# fg 2 拿到前台
sh while01.sh
[root@node01 day11]# jobs
[1]+ Running sh while01.sh &
[root@node01 day11]# fg 1
sh while01.sh
^C 终止
[root@node01 day11]# jobs
[root@node01 day11]#
通过while循环计算1加到100之和(请用1+2+3的方法)
[root@node01 day11]# vi while03.sh
#!/bin/sh
i=1
sum=0
while [ $i -le 100 ] ============>((i < 101))也可以
do
let sum=sum+i ((sum=sum+i))
let i=i+1 ((i++))
done
echo $sum
[root@node01 day11]# sh while03.sh
5050
[root@node01 day11]# vi while04.sh
#!/bin/sh
i=1
sum=0
while ((i < 101))
do
((sum=sum+i))
((i++))
done
echo $sum
[root@node01 day11]# cp while03.sh while05.sh
[root@node01 day11]# vi while05.sh
#!/bin/sh
i=1
sum=0
while [ $i -le 5 ]
do
let sum=sum+i
let i=i+1
done
echo $sum
[root@node01 day11]# sh while05.sh
15
用公式计算
[root@node01 day11]# vi sum01.sh
#!/bin/sh
((sum=10000000*(1+10000000)/2))
echo $sum
[root@node01 day11]# sh sum01.sh
50000005000000
[root@node01 day11]# time sh sum01.sh
50000005000000
real 0m0.004s
user 0m0.002s
sys 0m0.002s
[root@node01 day11]# vi while04.sh
#!/bin/sh
i=1
sum=0
while ((i < 1000000))
do
((sum=sum+i))
((i++))
done
echo $sum
[root@node01 day11]# time sh while04.sh
499999500000
real 0m6.885s
user 0m6.537s
sys 0m0.279s
使用while循环竖向打印10,9,8。。。1
[root@node01 day11]# vi while07.sh
#!/bin/sh
i=10
while ((i>0))
do
echo $i
let i=i-1
done
[root@node01 day11]# sh while07.sh
10
9
8
7
6
5
4
3
2
1
[root@node01 day11]# vi while08.sh (打偶数)
#!/bin/sh
i=10
while ((i>0))
do
echo $i
let i=i-2
done
[root@node01 day11]# sh while08.sh
10
8
6
4
2
[root@node01 day11]# vi while08.sh
#!/bin/sh
i=9
while ((i>0))
do
echo $i
let i=i-2
done
[root@node01 day11]# sh while08.sh
9
7
5
3
1
手机充值10远,每发一条短信话费(输出当前余额)1角5分,当余额低于1毛不能发短信,提示余额不足,请充值,请用while语句实现
[root@node01 day11]# vi while06.sh
#!/bin/sh
i=15
sum=1000
while ((sum>=i))
do
((sum=sum-i))
echo "send message:$sum"
done
echo “money is not enough:$sum”
[root@node01 day11]# sh while06.sh
send message,985
。。。。。
send message,70
send message,55
send message,40
send message,25
send message,10
“money is not enough:10”
[root@node01 day11]#
实例分析apache日志例子
问题1:计算apache一天的log中所有行的log各元素访问字节数的综合,给出实现程序。
cat a.log|while readline
do
done
-----------------
while read line
do
done
----------
exec while read line
do
done
===========================
awk '{print $10}' access_2010-12-8.log
head -1|awk '{print $10}' access_2010-12-8.log
#!/bin/sh
sum=0
i=0
while read line
do
i=$(echo $line|awk '{print $10}')
if expr $i + 0&>/dev/null
then
((sum=sum+i))
fi
done echo $sum
例子:10秒钟做一次rsync binlog推送,守护进程方式,写完脚本后台执行。
#!/bin/sh
while true
do
rsync -az /data/3306/mysql-bin* [email protected]::backup --password--file=/etc/rsync.password &
sleep 10
done
/data/day11/rsync_binlog.sh &
echo "/data/day11/rsync_binlog.sh &">>/etc/rc.local
三、循环总结
1、while循环的特长是执行守护进程以及我们希望循环不退出继续执行,用于频率小于1分钟循环处理(大于1分钟一般用crontab)
,其他的while循环几乎都可以用for循环替代。
2、case语句可以if语句替换,一般在系统启动脚本传入少量固定规则字符串,用case,其他普通判断多用if。
3、一句话,if,for语句最常用,其次while(守护进程),case(服务启动脚本)
四、总结进程管理命令
bg:后台运行
fg:挂起程序
jobs:显示后台程序
kill、pkill、killall:杀掉进程
crontab:设置定时
ps:查看进程
pstree:显示进程树
top:显示进程
nice:改变优先权
nohup:用户退出系统之后继续工作
pgrep:查找匹配条件的进程
strace:跟踪一个进程的系统调用情况 这个很好用(一个进程特别高可以跟踪pid)
ltrace:跟踪进程调用库函数的情况
vmstat:报告虚拟内存统计信息