在掌握了条件判断、循环结构、函数和数组操作后,本文将继续深入 Shell 脚本的进阶主题,包括 进程管理、信号处理 和 脚本性能优化,帮助你编写更高效、健壮的脚本。
一、进程管理
1. 后台运行进程
使用 &
符号让命令在后台运行,释放当前终端:
# 后台执行耗时任务(如压缩文件)
tar -czf backup.tar.gz /data &
2. 查看与管理后台任务
• jobs
:列出当前终端的所有后台任务(显示任务编号和状态)。
• fg %n
:将任务编号为 n
的后台任务切换到前台。
• bg %n
:将暂停的任务切换到后台继续运行。
示例:后台任务管理
sleep 30 & # 后台执行 sleep
jobs # 输出:[1] + running sleep 30
fg %1 # 切换 sleep 到前台
3. 等待进程结束
wait
命令用于等待一个或多个后台进程完成:
command1 &
command2 &
wait # 等待所有后台进程结束
echo "所有任务已完成"
4. 获取进程状态
• ps
:查看进程信息(常用组合 ps aux
或 ps -ef
)。
• pgrep
:根据名称查找进程 ID。
• kill
:终止进程(-9
表示强制终止)。
示例:检查进程是否存在
pid=$(pgrep -f "nginx")
if [ -n "$pid" ]; then
echo "Nginx 进程运行中 (PID: $pid)"
else
echo "Nginx 未启动"
fi
二、信号处理
1. 常见信号类型
信号 | 值 | 说明 |
---|---|---|
SIGINT | 2 | 中断信号(如 Ctrl+C) |
SIGTERM | 15 | 终止进程(默认 kill 行为) |
SIGKILL | 9 | 强制终止(不可被捕获) |
2. 使用 trap
捕获信号
在脚本中定义信号处理逻辑:
trap '处理代码' 信号列表
示例:优雅退出脚本
trap 'echo "捕获中断!清理中..."; rm -f tmpfile; exit 1' SIGINT
while true; do
echo "运行中..."
sleep 1
done
当按下 Ctrl+C
时,输出提示并清理临时文件。
三、脚本性能优化
1. 减少子 Shell 开销
• 避免在循环中频繁使用管道 |
或反引号 `
,改用进程替换或临时文件。
• 使用 $(( ))
替代外部命令 expr
进行数学运算。
优化前(低效):
for i in {1..100}; do
result=`expr $i \* 2`
done
优化后(高效):
for i in {1..100}; do
result=$((i * 2))
done
2. 并行处理任务
利用后台进程和 wait
实现并行执行:
# 同时下载多个文件
download_files() {
wget -q $1 &
}
files=("http://example.com/file1" "http://example.com/file2")
for url in "${files[@]}"; do
download_files "$url"
done
wait
echo "所有文件下载完成"
3. 使用 time
命令分析耗时
测量脚本或命令的执行时间:
time {
# 需要测试的代码块
find / -name "*.log" > results.txt
}
四、其他实用技巧
1. 关联数组(Bash 4.0+)
定义键值对结构,适合存储配置或映射关系:
declare -A user_roles
user_roles=(["Alice"]="admin" ["Bob"]="user")
# 获取所有键
echo "用户列表:${!user_roles[@]}"
# 获取值
echo "Alice 的角色:${user_roles[Alice]}"
2. 正则表达式匹配
使用 =~
进行正则匹配(需在 [[ ]]
条件中):
email="user@example.com"
if [[ $email =~ ^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$ ]]; then
echo "邮箱格式正确"
else
echo "无效邮箱"
fi
总结
本文深入讲解了 Shell 脚本的以下进阶内容:
- 进程管理:后台任务、进程状态监控与等待。
- 信号处理:通过
trap
实现优雅退出和资源清理。 - 性能优化:减少子 Shell 开销、并行处理和耗时分析。
建议结合以下场景练习:
- 编写一个监控服务状态的脚本,自动重启崩溃的进程。
- 使用并行下载加速批量文件的获取。
后续内容将探讨 脚本安全实践、跨平台兼容性 和 与外部工具的集成(如 awk
、sed
)。
在脚本中使用 trap
捕获信号,可以避免资源泄漏和中间文件残留! 🔧