如何在含其他输出的Bash脚本中正确使用tqdm进度条
在含额外输出的脚本中使用tqdm的简化方案
问题背景
当bash脚本的循环中同时存在进度控制消息和其他标准输出时,直接通过管道将所有输出传给tqdm会导致进度条异常:比如设置总数为10,但实际传递了30条消息,最终进度条会变为极简样式(如30it [00:04, 6.01it/s])。
原问题示例脚本:
for i in $(seq 10); do # 进度控制消息 echo "progress" # 干扰进度条的其他输出 echo "b" echo "c" # 模拟任务执行 sleep 0.5 done | tqdm --total 10 --null;
用户已通过文件描述符分离实现了需求,现寻求更直接的方案。
更简洁的实现方法
方法1:将非进度输出重定向到stderr
这是最通用且易读的方案——把不需要传给tqdm的消息直接输出到stderr,管道仅传递进度控制消息:
for i in $(seq 10); do # 进度消息输出到stdout,通过管道传给tqdm echo "progress" # 其他消息输出到stderr,直接显示在终端,不进入管道 echo "b" >&2 echo "c" >&2 sleep 0.5 done | tqdm --total 10 --null
方法2:手动更新tqdm进度(Linux专属)
如果不想用管道,可以直接在循环内通过tqdm的后台进程手动更新进度,这种方式依赖/proc文件系统:
# 启动后台tqdm进程,获取其PID tqdm --total 10 >/dev/null & TQDM_PID=$! for i in $(seq 10); do # 向tqdm的标准输入写入1,触发进度更新 echo 1 > "/proc/$TQDM_PID/fd/0" # 其他消息正常输出到stdout echo "b" echo "c" sleep 0.5 done # 结束tqdm后台进程 kill $TQDM_PID
总结
优先选择方法1,它不需要复杂的文件描述符嵌套,代码简洁且跨平台,完美分离进度控制与其他输出。
内容的提问来源于stack exchange,提问作者IvanProsperi94
相关产品推荐
相关产品推荐

