Shell进度条核心是真实反映进展并实时刷新:百分比式适用于步骤明确任务,旋转符号用于不可量化场景,pv工具则提供可靠简洁方案。

Shell函数封装耗时任务并集成进度条,核心在于把“可度量的进展”和“终端实时刷新”结合起来。不是加个动画就叫进度条,关键要反映真实状态——比如文件拷贝中已写入字节数、循环处理中已完成项数、或命令执行阶段数。下面从实用角度拆解几种典型做法。
用百分比驱动的固定步长进度条
适用于总步骤明确的任务,例如执行100次API调用、遍历已知数量的配置项:
- 提前算出总次数(如total=100),用for((i=0; i控制循环
- 每次操作后计算当前比例:ratio=$((i * 100 / total))
- 用printf " [%-50s]%d%%" "$(printf '#%.0s' $(seq 1 $((ratio/2))))" "$ratio"动态渲染:每2%填一个#,保持50字符宽度对齐
- 结尾加echo换行,避免下一条提示被覆盖
用文件大小反馈的真实拷贝进度
适合cp、rsync等无法直接获取进度但目标文件持续增长的操作:
- 启动拷贝前获取源文件大小:src_size=$(stat -c '%s' "$src")(Linux)或src_size=$(stat -f '%z' "$src")(macOS)
- 后台运行拷贝,同时用while循环轮询目标文件当前大小:dst_size=$(stat -c '%s' "$dst" 2>/dev/null || echo 0)
- 按比例更新进度:ratio=$((dst_size * 100 / src_size)),限制最大为100
- 加入trap 'kill $!' INT,确保Ctrl+C能同时终止拷贝和进度监控进程
用旋转符号表示“正在运行”的轻量提示
当任务不可量化(如等待服务启动、执行未知耗时命令),只需传达“没卡住”即可:
- 定义符号数组:spinner=('|' '/' '-' '\')
- 用printf " [%c] 正在等待服务响应..." "${spinner[i%4]}"每0.2秒切换一次符号
- 配合wait $pid等待主任务结束,结束后打印成功或失败信息
- 这种提示不显示百分比,但消除用户焦虑效果明显
用pv替代自研,兼顾简洁与可靠性
对文件传输、压缩解压类操作,优先用现成工具而非手写逻辑:
- pv big.log | grep "ERROR" > errors.txt —— 显示日志过滤进度
- tar -cf - /data | pv -s $(du -sb /data | awk '{print $1}') | gzip > backup.tar.gz —— 精确标注总大小后显示压缩流进度
- 优点是无需判断平台差异、自动适配终端宽度、支持速率/ETA等高级字段,且pv本身极轻量(通常系统已预装或apt install pv即可)

















