shell(十一)while循环
程序员文章站
2022-03-16 10:34:44
...
一 while循环的应用场景
while循环工作中使用的不多,一般是守护进程程序或始终循环执行场景,其它循环计算,都会用for替换while
二 while循环的类型
当型(while)和直到(until)型循环语句
1、while条件句
while 条件
do
指令 …
done
# 先判断条件(满足)--->执行--->判断条件--->...
2、until条件句
# 不常用
until 条件
do
指令 ...
done
# 先判断条件(不满足)--->执行--->判断条件--->...
三 相关命令
sleep : 执行挂起指定的秒数
usleep:功能把进程挂起一段时间, 单位是微秒 #1000000us
# 说明:如果是分钟级别的则用--> 定时任务
三 实践
(1)每隔两秒打印系统的负载
#!/bin/bash
while true
do
uptime # 核心命令
sleep 2 # 两秒打印一次
done
# 可用 ctrl+c取消
# 说明: while true 表示条件永远为真,因此为死循环会一直执行,也即守护进程!
(2)让脚本后台运行
#!/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:报告虚拟内存统计信息
需求2:while实现1到100之和
#!/bin/bash
i=1;sum=0
while [ $i -le 100 ]
do
((sum+=$i))
((i++))
done
echo $sum
# 方法很多-->这里以一种炫技的方式进行
说明:shell本身不适合计算,效率!
注意:多使用成熟的算法,代码执行效率更高!
需求3:使用while循环竖向打印10、9、8…
#!/bin/bash
i=10
while [ $i -gt 0 ]
do
echo "$i"
((--i))
done
# 注意:与之前的做对比!
补充:vim脚本生成
需求4:手机充值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的逻辑!
需求5: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
需求6:计算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 # 最终存在内容则打印
需求7:读取一个文件,倒插入一个新的文件,清空原文件
#!/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(服务启动脚本)