目录
while条件句
while循环工作中使用的不多,一般是守护进程程序或始终循环执行场景,其他循环计算,替换while。
语法:
while 条件
do
指令
done
手机充值:发短信扣费,每次扣1角5,当费用低于1角5,就不能发了
# 例:每两秒屏幕输出负载值
while true
do
uptime
sleep 2
done
提示:while true 表示条件永远为真,因此会一直运行,像死循环一样,但是我们称呼为守护进程。
计算1+2+3...+100的值
#!/bin/sh
sum=0
i=1
while [ $i -le 100 ]
do
((sum=sum+i))
((i++))
done
echo $sum
while按行读文件的方式:
方式1:
exec <FILE
sum=0
while read line
do
cmd
done
方式2:
cat ${FILE_PATH} | while read line
do
cmd
done
方式3:
while read line
do
cmd
done<FILE
例1:计算apache一天的日志access.log中所有行的日志各元素的访问字节数的总和。给出实行程序,请用while循环实现
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
例2:一个oldboy.log日志10个ip记录,每10秒中一个导出到oldgirl.log中,倒腾到oldgirl.log里和oldboy.log内容一样。提示:oldboy的内容是逐渐减少的。
[root@rhel8 xiaopi]$echo 10.0.0.{1..10}|tr " " "\n" >oldboy.log
[root@rhel8 xiaopi]$cat oldboy.log
10.0.0.1
10.0.0.2
10.0.0.3
10.0.0.4
10.0.0.5
10.0.0.6
10.0.0.7
10.0.0.8
10.0.0.9
10.0.0.10
[root@rhel8 xiaopi]$vim while.sh
#!/bin/sh
apple1=oldboy.log
apple2=oldgirl.log
exec < $apple1
while read line
do
echo "$line" >>$apple2
sed -i 1d $apple1
echo "#cat $apple1" #打印出来命令
cat $apple1 #打印命令的输出,为了跟直观看出是什么命令
echo "#cat $apple2"
cat $apple2
sleep 2
done
until条件句
语法:
until 条件
do
指令
done
提示:until应用场合不多,仅做了解,until循环先执行循环后判断
休息命令
sleep 1 #<== 休息1秒
usleep 1000000 #<===休息1秒
一般用计划任务更多
后台执行脚本
防止客户端执行脚本中断的方法:.
1) sh while_01.sh &
2) nohup /server/scripts/uptime.sh &
3)screen保持会话,总结此命令
功能 | 用途 |
sh xxx.sh & | 把脚本xxx.sh放到后台执行 |
ctrl+c | 停止执行当前脚本或任务 |
ctrl+z | 暂停执行当前脚本或任务 |
bg | 把当前脚本或任务放到后台执行或继续执行暂停脚本 |
fg | 当前脚本或任务拿前台执行,如果有多个任务可以fg加任务序号调出 fg 1 |
jobs | 查看当前执行的脚本或任务 |
kill | [root@lvs01 ]# jobs [1]- running sh while. sh & [2]+ running sh while. sh & [root@lvs01 ~]# kill %2 [root@lvs01 ]# jobs [1]- running sh whilel. sh & [2]+ terminated sh whilel. sh |
进程管理
while循环小结
- while循环的特长是执行守护进程以及我们希望循环不退出持续执行的场景,用于
频率小于1分钟循环处理(crond),其他的while循环几乎都可以for 循环替代。
- 几乎所有case语可以if语句替换,一般在系统启动脚本传入少量固定规则字符串,用case
语句,其他普通判断多用if。
- 一句话,if,for 语句最常用,其次while(守护进程),case (服务启动脚本).
各个语句使用场景:
条件表达式,简短的判断(文件是否存在,字符串是否为空等).
if 取值判断,不同值数量较少的情况。
for 正常的循环处理,最常用!.
while守护进程,无限循环(sleep).
case服务启动脚本,菜单。
函数逻辑清晰,减少重复语句。
手机充值例题
手机充值10元,每发一次短信(输出当前余额)花费1角5分钱,当余额低于1角5分钱不能发短信,提示余额不足,请充值(可以允许用户充值继续发短信),请用while语句实现。
解答:单位换算。统一单位,统一成整数
10元=1000分,由于数额较大,短信500分/条
#!/bin/sh
TOTAL=1000
MSG=500
[ -f /etc/init.d/functions ]&& . /etc/init.d/functions
RED_COLOR='\E[1;31m'
YELLOW_COLOR='\E[1;33m'
RES='\E[0m'
color(){
case "$2" in
red)
echo -e "${RED_COLOR}$1$RES"
;;
yellow)
echo -e "${YELLOW_COLOR}$1$RES"
;;
esac
}
IS_NUM(){
expr $1 + 1 &>/dev/null
if [ $? -ne 0 -a "$1" -gt "0" ];then
return 1
fi
return 0
}
consum(){
read -p "Pls input your msg:" txt
read -p "Are you sure to send?{y|n}" opt1
case "$opt1" in
[yY]|[yY][eE][sS])
color "Send successfully!" yellow
echo "$txt" >>/home/xiaopi/message.txt
((TOTAL=TOTAL-MSG))
color "You have $TOTAL left!" yellow
;;
[nN]|[nN][oO])
echo "Canceled"
;;
*)
echo "Invalid input,this msg don't send"
;;
esac
}
charge(){
if [ $TOTAL -lt $MSG ];then
color "Money is not enough,Can you want to charge?{y|n}" red
read opt2
case "$opt2" in
[yY]|[yY][eE][sS])
while true
do
read -p "How much to charge?{INT}" charge
IS_NUM $charge && break || {
echo "Invalid input"
exit 100
}
done
((TOTAL=TOTAL+charge)) && echo "You have $TOTAL money."
if [ $TOTAL -lt $MSG ];then
charge
fi
;;
[nN]|[nN][oO])
echo "Your money have $TOTAL,no enough money to send msg"
charge
;;
*)
echo "Invalid input!"
charge
;;
esac
fi
}
main(){
while [ $TOTAL -ge $MSG ]
do
consum
charge
done
}
main