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 循环结构及相关语句综合实践

  1. while 循环的特长是执行守护进程,以及实现我们希望循环持续执行不退出的应用,适合用于频率小于 1min 的循环处理其他的 while 循环几乎都可以被 for 循环及定时任务 crontab 功能代替
  2. case 语句可以用 if 语句来替代,而在系统启动脚本时传入少量固定规则字符串的情况下,多用 case 语句,其他普通判断多用 if 语句
  3. 一句换场景,if 语句、for 语句最常用,其次是 while(守护进程)、case(服务启动脚本)

二. shell 脚本中各个语句的使用场景

  1. 条件表达式,用于简短的条件判断及输出(文件是否存在,字符串是否为空等)
  2. if 取值判断,多用于不同值数量较少的情况
  3. 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 $*

案例二: 手机充值并发送短信。这个案例并没有实际用途,可以当做一个综合练习玩玩的 以下功能:

  1. 充值,但重复充值金额不累计,充值后立即查询余额无法正常使用
  2. 发送短信,输入发送的条数和短信内容,当金额不足时,可以选择(y:充值,n:修改发送条数,o:返回菜单)
  3. 查询余额,只有当使用发送功能选择(o:返回菜单)时,查询才可以生常使用
  4. 退出,结束当前脚本
#!/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