Bash 脚本中的循环、函数 和 Linux 的进程管理 是 shell 编程与系统运维的核心内容。下面用清晰的结构和大量实用例子整理成笔记形式(2026 年视角,基于 bash 5.x+ 常用写法)。
1. Bash 三种循环语句
| 循环类型 | 关键字 | 适用场景 | 语法特点 | 退出条件 |
|---|---|---|---|---|
| for | for … in | 已知列表/范围/文件列表 | 最常用、最安全 | 遍历完列表 |
| while | while 条件 | 条件为真时继续(次数未知) | 类似其他语言 while | 条件为假 |
| until | until 条件 | 条件为假时继续(直到条件为真) | while 的“反向”版本 | 条件为真 |
1.1 for 循环(最常用)
# 写法1:遍历列表(最常见)
for var in apple banana "cherry pie" orange; do
echo "水果:$var"
done
# 写法2:用通配符遍历文件
for file in *.sh; do
echo "脚本文件:$file"
chmod +x "$file" # 注意加引号防空格文件名
done
# 写法3:C 风格(数字范围最常用)
for ((i=1; i<=10; i+=2)); do
echo "奇数:$i"
done
# 写法4:结合 seq 或 brace expansion(推荐)
for i in {1..5}; do echo $i; done # 1 2 3 4 5
for i in $(seq 10 2 20); do echo $i; done # 10 12 14 ... 20
1.2 while 循环
# 经典:读取文件逐行(最安全写法)
while IFS= read -r line; do
echo "行内容:$line"
done < data.txt
# 条件循环
count=1
while [ $count -le 5 ]; do
echo "计数:$count"
((count++))
done
# 死循环 + break 退出(超级常用)
while true; do
read -p "输入 q 退出:" input
[[ $input == "q" ]] && break
echo "你输入了:$input"
done
1.3 until 循环(较少用,但某些场景很优雅)
# 等待某个文件出现
until [ -f /tmp/ready.flag ]; do
echo "等待就绪文件出现..."
sleep 2
done
echo "文件已就绪,开始处理!"
# 计数到 10
i=1
until (( i > 10 )); do
echo $i
((i++))
done
循环控制:break / continue
break:跳出整个循环continue:跳过本次,进入下一次迭代break 2/continue 2:跳出/跳过外层第 2 层循环(嵌套时有用)
for i in {1..5}; do
for j in {a..c}; do
[[ $j == "b" ]] && continue 2 # 跳过外层本次
echo "$i-$j"
done
done
2. Bash 函数
Bash 函数是脚本模块化的核心。现代写法强烈推荐使用 local 变量 + return 状态码 + echo 返回数据。
基本语法
# 定义方式1(推荐)
greet() {
local name="$1" # 局部变量,防止污染全局
echo "你好,$name!"
return 0 # 成功返回 0(约定俗成)
}
# 定义方式2(旧式,也合法)
function greet2 {
echo "Hi, $1"
}
# 调用
greet "重阳"
greet2 "Warsaw"
# 带返回值(状态码 + 数据)
add() {
local sum=$(( $1 + $2 ))
echo "$sum" # 通过 stdout 返回数据(最常用)
return 0 # 状态码
}
result=$(add 38 64) # 捕获 echo 输出
echo "结果:$result" # 102
echo "状态码:$?" # 0
常见陷阱与最佳实践
- 不要直接用全局变量传结果 → 容易冲突
- 推荐:
echo返回主要数据,return只返回 0~255 状态码 - 参数:
$1 $2 ... $@ $* $# $@(推荐) vs$*:带引号时行为不同(处理空格参数)
show_args() {
echo "参数个数:$#"
echo "所有参数(@):$@"
for arg in "$@"; do echo "→ $arg"; done
}
show_args "hello world" bash "Warsaw PL"
3. Linux 进程管理常用命令(2025-2026 实用组合)
| 目的 | 常用命令组合 | 说明与示例 |
|---|---|---|
| 查看所有进程 | ps aux / ps -ef | ps aux | grep nginx |
| 实时监控(交互) | top / htop(需安装) / btop(现代替代) | htop 里按 F9 kill 进程 |
| 树形查看进程关系 | pstree -p | 显示 PID 和父子关系 |
| 查找进程 PID | pgrep nginx / pidof nginx | pgrep -l python 带进程名 |
| 温和终止 | kill PID / kill -15 PID | SIGTERM,让进程自己清理 |
| 强制杀死 | kill -9 PID / pkill -9 -f "python app" | SIGKILL,无法捕获,危险但有效 |
| 按名字杀 | pkill nginx / killall -9 ffmpeg | pkill 支持模式,killall 精确进程名 |
| 后台运行 | command & / nohup command & | nohup 防终端关闭挂起 |
| 管理后台任务 | jobs / fg %1 / bg %2 / Ctrl+Z | Ctrl+Z 暂停 → bg 后台继续 → fg 拉回前台 |
| 脱离终端长期运行 | nohup python script.py > out.log 2>&1 & | 或使用 screen / tmux / systemd 服务 |
经典组合示例
- 查找并杀掉卡死的进程
ps aux | grep -i chrome | grep -v grep
pkill -9 -f "chrome --type=renderer"
- 后台启动服务并记录日志
nohup ./my_server --port 8080 > server.log 2>&1 &
tail -f server.log
- 暂停/恢复/杀后台任务
sleep 3600 & # 后台睡1小时
jobs # 显示 [1] Running ...
fg %1 # 拉回前台(可 Ctrl+C 杀)
# 或
kill %1 # 直接杀后台任务
小练习建议
- 写一个函数
backup_files,接收目录路径,备份所有 .txt 文件到 backup_日期/ 下 - 用 until 循环等待某个端口(例如 3306)被占用(netstat/ss/netcat 测试)
- 写脚本:循环监控某个进程(nginx),如果不存在则启动它(while + pgrep)
有哪部分想看更详细的完整脚本示例?
或者想深入某个工具(如 tmux/screen 的多会话管理、systemd 服务编写)?随时说~