shell无真正多线程,通过&启动后台进程并用wait协调实现类并发;需控制并发数、捕获退出状态、避免变量覆盖与i/o冲突。

Shell 本身不支持真正的多线程(没有线程概念),但可以通过后台进程(&)+ wait 控制模拟并发执行效果,这是 Shell 中实现“类多线程”并发的通用做法。
用 & 启动并发任务
在命令末尾加 & 可让命令在后台运行,Shell 不会等待它结束就继续执行下一行。多个命令并行启动后,用 wait 等待全部完成。
- 每条耗时命令后加
&,例如:sleep 2 & - 所有后台任务启动完后,加
wait阻塞直到所有子进程结束 - 避免直接写
cmd1 & cmd2 & wait,应确保wait在所有&之后执行
控制并发数量(限流)
无限制启后台进程可能导致资源耗尽。可用 文件描述符 + flock 或简单计数器限制同时运行的任务数。
- 用
jobs -r | wc -l统计当前运行中的后台任务数 - 循环中检查该数量,超过阈值则
wait -n(等待任一后台任务退出) - 示例:最多允许 3 个并发
curl请求,每次新增前检查[[ $(jobs -r | wc -l) -ge 3 ]] && wait -n
捕获每个任务的退出状态
后台任务的 $? 无法直接获取,需用临时文件、命名管道或 wait PID 获取指定进程退出码。
- 启动时记录 PID:
cmd & pid=$! - 后续用
wait "$pid"等待该任务,并得到它的退出状态 - 或用
wait -n配合$?获取最先结束任务的状态(适合“只要一个成功就行”的场景)
避免常见坑
Shell 并发容易因变量覆盖、I/O 冲突或信号处理出错。
- 不要在后台命令中直接修改父 Shell 的变量(子 shell 不影响父 shell)
- 重定向输出到不同文件,避免多个任务写同一 stdout/stderr 导致混乱
- 慎用
set -e:后台命令失败不会触发退出,需显式检查 - 脚本退出前确保所有后台任务已
wait,否则可能提前结束











