while
是 Shell 脚本中用于 条件循环 的控制结构,只要条件为真,就重复执行代码块。特别适合处理 逐行读取文件、监控进程、无限循环 等场景。
1. while
循环基础语法
1.1 基本格式
while [ 条件 ]
do
循环体命令
done
[ 条件 ]
可以是 测试语句、命令返回值 或 算术表达式。do
和done
标记循环体的开始和结束。
1.2 三种条件写法
(1) 测试条件
count=1
while [ "$count" -le 5 ]
do
echo "计数: $count"
let count++
done
(2) 命令返回值
# 当 ping 成功时循环
while ping -c1 baidu.com &>/dev/null
do
echo "网络畅通"
sleep 5
done
echo "连接失败,请检查网络......"
(3) 无限循环【死循环】
while true # 或 `:`
do
echo "持续运行中..."
sleep 1
done
2. 运维实战案例
案例 1:逐行读取文件
[root@lichu ~]# vim while3.sh
#!/bin/bash
while read line
do
echo "行内容: $line"
done < /etc/hosts
要求:提取passwd文件中的用户名、UID、SHELL
[root@lichu ~]# head -n1 /etc/passwd
root:x:0:0:root:/root:/bin/bash
传统版:
[root@lichu ~]# vim while4.sh
#!/bin/bash
while read line
do
username=$(echo $line |awk -F":" '{print $1}')
useruid=$(echo $line |awk -F":" '{print $3}')
usershell=$(echo $line |awk -F":" '{print $7}')
echo "用户名: $username, UID: $useruid, SHELL: $usershell"
done < /etc/passwd
优化版:
[root@lichu ~]# vim while5.sh
#!/bin/bash
while read line
do
IFS=':' read username _ useruid _ _ _ usershell <<<$line
echo "用户名: $username, UID: $useruid, SHELL: $usershell"
done < /etc/passwd
案例 2:监控进程是否存在
#!/bin/bash
process="nginx"
while ! pgrep "$process" &>/dev/null
do
echo "$process 未运行,尝试启动..."
systemctl start "$process" &>/dev/null
sleep 3
done
echo "$process 已运行!"
[root@lichu ~]# bash while5.sh
nginx 未运行,尝试启动...
nginx 未运行,尝试启动...
nginx 未运行,尝试启动...
nginx 已运行!
案例 3:用户输入验证
#!/bin/bash
while true
do
read -p "请输入数字 (1-5): " num
if [[ "$num" =~ ^[1-5]$ ]]; then
echo "输入有效: $num"
break
else
echo "输入无效,请重试!"
fi
done
案例 4:磁盘空间监控
#!/bin/bash
threshold=90 # 阈值 90%
while [ "$(df -h / | awk 'NR==2 {print $5}' | tr -d '%')" -ge "$threshold" ]
do
echo "警告: 磁盘使用率超过 $threshold%,请清理!" | mail -s "磁盘告警" root
sleep 3600 # 每小时检查一次
done
echo "当前磁盘空间使用率: $(df -h / | awk 'NR==2 {print $5}'),未超过阈值"
3. 高级技巧
3.1 嵌套循环
while true
do
for service in nginx mysql redis
do
if ! systemctl is-active -q "$service"; then
echo "$service 未运行,尝试重启..."
systemctl restart "$service"
fi
done
sleep 60 # 每分钟检查一次
done
3.2 结合 case
处理菜单
#!/bin/bash
while true
do
clear
echo "系统工具箱"
echo "1. 检查磁盘空间"
echo "2. 检查内存使用"
echo "3. 检查网络连接"
echo "4. 退出"
read -p "请选择操作 (1-4): " choice
case "$choice" in
1)
echo -e "\n磁盘空间信息:"
df -h
;;
2)
echo -e "\n内存使用信息:"
free -h
;;
3)
echo -e "\n网络连接测试:"
ping -c2 baidu.com
;;
4|q)
echo "退出系统工具箱。"
exit 0
;;
*)
echo "无效输入!请输入1-4的数字。"
;;
esac
read -p "按Enter键继续..."
done