提升 shell 脚本效率需:一、缓存外部命令结果避免循环调用;二、优先使用内置命令如[[、printf、cd;三、减少管道与子shell,改用pgrep、重定向或数组;四、用exec预绑定文件描述符优化i/o。

如果您编写了 Linux shell 脚本但发现执行缓慢、CPU 占用高或响应延迟明显,则可能是由于脚本中存在低效的命令调用、冗余的子进程创建或不当的数据处理方式。以下是提升 shell 脚本运行效率的具体实践方法:
一、避免重复执行外部命令
在循环中反复调用 date、hostname、pwd 等外部命令会频繁 fork 子进程,显著拖慢脚本速度。应将结果缓存于变量中复用,减少系统调用开销。
1、将命令结果赋值给变量,而非在循环内重复执行:date_str=$(date +%Y%m%d)
2、检查脚本中所有 for/while 循环体,定位并移除循环内部的 $(date)、$(hostname) 等子命令调用。
3、对需多次使用的路径信息,使用 PWD 内置变量替代 $(pwd)。
二、优先使用内置命令替代外部命令
Bash 内置命令(如 printf、test、[、cd)不触发子进程,比对应外部命令(/usr/bin/printf、/usr/bin/[)更快且更轻量。合理替换可降低 fork 开销与磁盘 I/O。
1、用 [[ ]] 替代 [ ] 进行条件判断,支持正则和模式匹配且无需调用外部程序。
2、用 printf 替代 echo,尤其在批量输出或格式化场景下更可控、更高效。
3、用 builtin cd 或直接使用 cd(默认即内置)替代 /usr/bin/cd。
三、减少管道与子 shell 的滥用
每条管道(|)都会创建子 shell 并启动新进程,多级管道(如 cmd1 | cmd2 | cmd3)导致三层进程嵌套。应合并逻辑、改用重定向或数组处理,避免无谓的进程分裂。
1、将 ps aux | grep nginx | wc -l 改为 pgrep -f nginx | wc -l,减少一个管道环节。
2、对文本逐行处理时,避免 cat file | while read line; do ...; done,改用 while read line; do ...; done 防止 while 运行在子 shell 中导致变量失效。
3、使用 mapfile -t array 一次性读入数组,再用 for 遍历,避免逐行 fork read。
四、优化字符串操作与参数扩展
调用 sed、awk、cut 等外部工具处理字符串会产生额外进程。Bash 4.0+ 支持强大的参数扩展语法,可在纯 shell 环境中完成截取、替换、大小写转换等操作,零开销。
1、用 ${var#*/} 替代 echo "$var" | cut -d'/' -f2- 提取路径后缀。
2、用 ${var// /_} 替代 echo "$var" | sed 's/ /_/g' 执行全局空格替换。
3、用 ${var,,} 实现小写转换,替代 echo "$var" | tr 'A-Z' 'a-z'。
五、合理使用 exec 重定向与文件描述符
频繁打开/关闭文件(如循环中 > file 或 >> file)引发大量系统调用。通过提前用 exec 绑定文件描述符,实现单次打开、多次写入,显著提升 I/O 效率。
1、在脚本开头执行 exec 3> output.log,建立文件描述符 3 指向日志文件。
2、循环体内使用 printf "%s\n" "$msg" >&3 写入,避免每次重开文件。
3、脚本结束前执行 exec 3>&- 关闭描述符 3。











