Shell脚本性能差主因是写法不当:大量无谓进程创建、重复读写、低效判断或阻塞等待;优化核心为减少子进程、避免重复计算、用对工具、控制I/O节奏。

Shell脚本性能差,往往不是因为“语法太慢”,而是写法不当导致大量无谓的进程创建、重复读写、低效判断或阻塞等待。优化核心是减少子进程、避免重复计算、用对工具、控制I/O节奏。
减少不必要的子进程调用
每次执行 ls、cut、grep、awk 等命令都会 fork 一个新进程,开销明显。尤其在循环中反复调用,性能急剧下降。
- 用 Shell 内置功能替代外部命令:比如 ${var#pattern} 截取字符串,比 echo $var | cut -d'_' -f2 快得多
- 循环内避免重复调用 date 或 hostname —— 提前存入变量
- 用 [[ ]] 而非 [ ](即用内置 test),支持正则和模式匹配,不启动外部 /bin/[
批量处理优于逐行处理
一行一命令(如 for line in $(cat file))本质是把文件内容全展开成参数,既耗内存又易被空格/换行破坏;且每轮都触发一次命令执行。
- 改用 while read 流式读取:while IFS= read -r line; do ...; done
- 把多条管道合并:比如 ps aux | grep nginx | wc -l 可换成 pgrep nginx | wc -l,更精准且少启进程
- 大文件统计/过滤优先交给 awk 或 sed 一次性完成,别用 shell 循环+多个 grep
合理使用数组与变量缓存
频繁读文件、查环境、解析命令输出,是隐形瓶颈。能缓存就缓存,能复用就不重算。
- 路径、配置值、服务状态等静态信息,首次获取后存入变量,后续直接引用
- 需要多次遍历的数据,先读入数组:mapfile -t lines ,再用 for item in "${lines[@]}"
- 避免在循环里反复执行 $(basename "$path") 或 $(dirname "$path") —— 提前提取好
警惕隐式 I/O 和阻塞操作
看似简单的语句可能触发磁盘读写或网络等待,尤其在高并发或低配环境中影响显著。
- stat、find、realpath 默认访问文件系统,大量调用时延迟明显;加 -L 或缓存结果
- 远程命令(如 ssh、curl)务必设超时:timeout 3 curl -s http://api/
- 日志写入别用 echo ... >> log 频繁打开关闭文件,改用单次重定向:{ cmd1; cmd2; } >> log











