一 while循环的应用场景
while循环工作中使用的不多,一般是'守护进程'程序或'始终循环'执行场景,其它'循环计算',都会用'for替换'while
二 while循环的类型
当型'while'和直到'until'型循环语句
① while条件句
while <条件表达式>
do
指令 …
done
# 先判断条件(满足)--->执行--->判断条件--->...
② until条件句
# 不常用
until 条件
do
指令 ...
done
# 先判断条件(不满足)--->执行--->判断条件
备注: '至少'执行一次
三 相关命令
sleep : 执行挂起'指定'的秒数
usleep: 功能把'进程挂起'一段时间,单位是'微秒 '
'1000000us' --> '1s'
crontab: 如果是'分钟级别'的定时任务
三 实践
① 每隔两秒打印系统的负载
#!/bin/bash
while true
do
uptime # 核心命令
sleep 2 # 两秒打印一次
done
# 可用 ctrl+c取消
# 说明: while true 表示条件永远为真,因此为死循环会一直执行,也即守护进程!
② 让脚本后台运行
#!/bin/bash
while true
do
uptime >> /mnt/log
sleep 2
done
# 执行:后台运行
sh while2.sh &
# 检测
tail -f /mnt/log
# 说明:即使把窗口关闭还是会运行
# 执行脚本,跟数据库相关的,插入数据等,一定不要命令行输出,放到后台执行
# 客户端突然端了怎么办,执行到哪了
相关:防止客户端执行脚本终端
# 防止客户端执行脚本中断的方法。
1、sh while.sh & # 通过kill -p pid 关闭
2、nohup while.sh &
# 说明:上述是开发人员常用的
3、screen保持回话 # 比较高级
ctl+c:停止执行当前脚本或任务
ctrl+z:暂停执行当前脚本或任务
bg:把当前脚本(前台)或任务放入后台执行
fg:当前脚本或任务进行前台执行,如果有多个任务,可以fg加任务编号调出
jobs:查看当前执行的脚本或任务
进程管理命令
# 进程管理常用16个命令
bg:后台运行
fg:挂起程序
jobs:显示后台程序
kill、killall、pkill:杀掉进程
crontab:设置定时
ps:查看进程
pstree:显示进程状态树
top:显示进程
nice:改变优先权
nohup:用户退出系统之后继续工作
pgrep:查找匹配条件的进程
strace:跟踪一个进程的系统调用情况(strace + pid)
ltrace:跟踪进程调用库函数的情况
vmstat:报告虚拟内存统计信息
③ while实现1到100之和
#!/bin/bash
i=1;sum=0
while [ $i -le 100 ]
do
((sum+=$i))
((i++))
done
echo $sum
# 方法很多-->这里以一种炫技的方式进行
说明:shell本身'不适合计算',效率'低'
注意:多使用'成熟的算法',代码执行'效率'更高
④ 使用while循环竖向打印10、9、8…
#!/bin/bash
i=10
while [ $i -gt 0 ]
do
echo "$i"
((--i))
done
'注意':与之前的做对比!
'补充':vim'脚本'生成
⑤ 手机充值10元,每发一次短信花费0.15元,当前余额小于0.15元不能发短信,提示余额不足,请充值,可以允许用户充值后继续发短信
#!/bin/bash
# 1元是100分
# 余额的初始化
total=0
# 提示-->选项
menu='
1:充值
2:发送信息
3:退出
'
# 充值
pay(){
read -t 10 -p "Pls input pay money:" num
# 输入的不是整数
expr ${num} + 1 &>/dev/null
[ $? -ne 0 ]&&{
echo "Input error"
return 1
}
# 输入的合法的整数
if [ ${num} -gt 0 ];then
# 变量都是全局的,可以在其它地方引用!
total=$(( $total + $num * 100 ))
else
echo "Input error"
return 1
fi
}
# 发短信
send(){
if [ ${total} -gt 15 ];then # 是不是余额小于0.15元
echo "send messages is ok."
total=$(( $total - 15 ))
else
echo "余额不足!"
fi
}
while true
do
echo "当前余额:${total}"
echo ${menu}
read -t 10 -p "Pls input a num:" choice # 与前面的menu对应
case ${choice} in
1) pay # 冲值后不退出,用while循环!
;;
2) send
;;
3) exit 0 # 结束充值
;;
*)
esac
done
# 说明:主要的和i锻炼shell的逻辑!
⑥ while按行读取文件的方式
# 方式一
exec <FILE
sum=0
while read line
do
cmd
done
# 方式二
cat ${FILE_PATH} | while read line
do
cmd
done
# 方式三
while read line
do
cmd
done<FILE
⑦ 计算apache一天的日志中所有行的各元素的访问字节数的总和
#/bin/bash
exec access.log # 读取日志
while read line
do
i=`echo $line|awk '{print $10}' # 获取内容`
expr $i + 1 &>/dev/null # 判断是不是整数
if [ $? -ne 0 ];then
continue
fi
((sum+=i))
done
[ -n "$sum" ] && echo $sum # 最终存在内容则打印
⑧ 读取一个文件,倒插入一个新的文件,清空原文件
#!/bin/bash
file=/root/read.sh
num=`wc -l ${file}|awk -F ' ' '{print $1}'`
while [ ${num} -gt 0 ]
do
line=`tail -1 ${file}` # 文件倒数一行的内容
echo ${line}
echo ${line}>>/root/read_bak.sh
sed -i '$d' ${file} # 把读入此行的内容删除
num=`wc -l ${file}|awk -F ' ' '{print $1}'` # 下一行内容的写入
done
三 while循环小结
1、while循环的特长是执行'守护进程'以及我们希望循环'不退出'持续执行的场景,用'频率小于1分钟'的循环处理,其他的while循环几乎都可以'被for循环替代'
2、几乎所有的case语句都可以用if语句替换,一般在系统启动脚本传入'少量固定规则'字符串,用case语句,其他普通判断多用if
3、工作中if和for'最常用',其次while(守护进程)和case(服务启动脚本)