天天看点

shell编程(十二)while循环

一    while循环的应用场景

while循环工作中使用的不多,一般是'守护进程'程序或'始终循环'执行场景,其它'循环计算',都会用'for替换'while
           

二    while循环的类型

当型'while'和直到'until'型循环语句
           

①  while条件句

while <条件表达式>

do

      指令 …

done

# 先判断条件(满足)--->执行--->判断条件--->...
           

②  until条件句

# 不常用

until 条件

do

      指令 ...
done

# 先判断条件(不满足)--->执行--->判断条件

备注: '至少'执行一次
           

三    相关命令

sleep和usleep

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保持回话 # 比较高级
           

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中各种符号的说

说明:shell本身'不适合计算',效率'低'

注意:多使用'成熟的算法',代码执行'效率'更高
           

④  使用while循环竖向打印10、9、8…

#!/bin/bash
i=10
while [ $i -gt 0 ]
  do
    echo "$i"
    ((--i))
  done

'注意':与之前的做对比!

'补充':vim'脚本'生成
           

NAT相关的

⑤  手机充值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的逻辑!
           

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(服务启动脚本)
           

继续阅读