while 循环语句
while 循环语句语法格式为:
while < 条件表达式 >
do
指令
done
有关脚本运行的相关用法
命令 | 说明 |
---|---|
sh file.sh & | 把 file.sh 脚本放到后台运行(后台运行脚本的常用方法) |
ctl+c | 停止执行当前脚本或任务 |
ctl+z | 暂停执行当前脚本或任务 |
bg | 把当前脚本或任务放到后台执行 |
fg | 把当前脚本或任务放到前台执行。如果是多个脚本,需加编号,如: fg 2 |
jobs | 查看当前执行的脚本或任务 |
kill | 关闭执行的脚本任务 |
有关进程管理的 Linux 相关命令
命令 | 说明 |
---|---|
kill、killall、pkill | 杀掉进程 |
ps | 查看进程 |
pstree | 显示进程状态树 |
top | 显示进程 |
renice | 改变优先权 |
nohup | 用户退出系统之后继续工作 |
pgrep | 查找匹配条件的进程 |
strace | 跟踪一个进程的系统调用情况 |
ltrace | 跟踪进程调用库函数的情况 |
小结
一. while 循环结构及相关语句综合实践
- while 循环的特长是执行守护进程,以及实现我们希望循环持续执行不退出的应用,适合用于频率小于 1min 的循环处理其他的 while 循环几乎都可以被 for 循环及定时任务 crontab 功能代替
- case 语句可以用 if 语句来替代,而在系统启动脚本时传入少量固定规则字符串的情况下,多用 case 语句,其他普通判断多用 if 语句
- 一句换场景,if 语句、for 语句最常用,其次是 while(守护进程)、case(服务启动脚本)
二. shell 脚本中各个语句的使用场景
- 条件表达式,用于简短的条件判断及输出(文件是否存在,字符串是否为空等)
- if 取值判断,多用于不同值数量较少的情况
- for 最常用于正常的循环处理中
案例一: 猜数字 随机生成一个 100 以内的数字,让用户输入数字来猜。游戏规则:输入的必须是数字,猜错时出现大小提示,才对时给出所用次数
#!/bin/bash
total=0
RETVAL=0
key=$((RANDOM%100))
echo "Let's play the guessing game!"
echo "key:$key"
panduan(){
read -p "input num: " num
expr $num + 1 &>/dev/null
RETVAL=$?
if [ $RETVAL -ne 0 ];then
echo "number number !!!"
panduan
fi
}
guess(){
((total++))
if [ $num -lt $key ];then
echo "It is too small"
panduan
elif [ $num -gt $key ];then
echo "It is too big"
panduan
else
echo "Guess right"
echo "yi gong cai le $total ci"
exit 0
fi
}
main(){
panduan
while true
do
guess
done
}
main $*
案例二: 手机充值并发送短信。这个案例并没有实际用途,可以当做一个综合练习玩玩的 以下功能:
- 充值,但重复充值金额不累计,充值后立即查询余额无法正常使用
- 发送短信,输入发送的条数和短信内容,当金额不足时,可以选择(y:充值,n:修改发送条数,o:返回菜单)
- 查询余额,只有当使用发送功能选择(o:返回菜单)时,查询才可以生常使用
- 退出,结束当前脚本
#!/bin/bash
RETVAL=0
balance=0
menu(){
cat << EOF
1) Recharge
2) Send information
3) Query
4) exit
EOF
read -p " please enter a number: " num
case $num in
1)
echo "Welcome to chongzhi !"
recharge
;;
2)
echo "Welcome Check the balance !"
send
;;
3)
echo "Welcome to the query interface !"
selects
;;
4)
echo "Looking forward to your next arrival !"
exit
;;
*)
echo "Tips:{1|2|3|4}"
menu
esac
}
recharge(){
read -p "please enter to RMB: " rmb
expr $rmb + 1 &>/dev/null
RETVAL=$?
if [ $RETVAL -ne 0 ];then
echo "please input num"
recharge
fi
echo "$rmbs Rechargs success"
((rmbs=$rmb + $balance))
menu
}
send(){
while true
read -p "send several messages: " strips
expr $strips + 1 &>/dev/null
RETVAL=$?
if [ $RETVAL -ne 0 ];then
echo "please input num"
send
fi
((count=$strips * 15))
do
if [ $count -gt $rmbs ];then
echo "Insufficient amount !!!"
read -p "Recharge(y|n|o) ?" or
if [ $or = y -o $or = Y ];then
recharge
elif [ $or = n -o $or = N ];then
send
else
menu
fi
else
read -p "Please input information content: " input
echo "sending:$input send success"
((balance=$rmbs - $count))
echo "Balance: $balance"
fi
((rmbs=$rmbs - $count))
done
}
selects(){
echo "Query:$balance"
menu
}
menu $*
案例三: 使用 while 守护进程的方式监控网站,每隔 10s 检测一次网站是否正常
#!/bin/bash
. /etc/init.d/functions
count=0
url_list=(
www.baidu.com
blog.51cto.com
www.taobao.com
www.192.168.80.123.com
)
waits(){
echo -n "3s run after"
for((i=0;i<3;i++))
do
echo -n .
sleep 1
done
echo
}
url(){
waits
for((i=0; i<`echo ${#url_list[*]}`; i++))
do
wget -o /dev/null -T 3 --tries=1 --spider ${url_list[$i]}>/dev/null 2>&1
if [ $? -eq 0 ];then
action "${url_list[$i]}" /bin/true
else
action "${url_list[$i]}" /bin/false
fi
done
((count++))
}
main(){
while true
do
url
echo "------count:$count------"
sleep 10
done
}
main
while 循环按行读文件
方法一:
cat 文件|while read line
do
命令
done
方法二:
while read line
do
命令
done<文件
案例一: 编写一个 shell 脚本,实现 cat 命令的基本功能
#!/bin/bath
while read line
do
echo $line
done</home/shell/fun.sh
案例二: 编写 shell 脚本,根据短时间内的 PV 量封掉对应 ip,解决类 DoS 的功能
#!/bin/bash
count=0
while true
do
netstat -an|grep EST|awk -F '[ :]+' '{print $6}'|sort|uniq -c>ip.log
exec<ip.log
while read line
do
pv=`echo $line|awk '{print $1}'`
ip=`echo $line|awk '{print $2}'`
if [ $pv -gt 10 ]&&[ `iptables -nL|grep $ip|wc -l` -eq 0 ];then
iptables -t filter -I INPUT -s $ip -j DROP
echo "sun success"
fi
done
((count++))
sleep 10
echo "---$count---"
done