gnome-terminal中bash导致tqdm进度条position参数位置异常

问题说明
编辑补充:该问题由bash终端配置导致,并非tqdm本身的功能bug。
通过threading.Thread创建3个下载任务时,已为每个任务绑定的tqdm进度条明确指定position参数,但实际运行会出现两个异常:
- 任务完成后,进度条会无视预先分配的位置,移动到终端顶部
- 最底部的任务完成后会自动跳转至新行,打断终端后续输入
从附图可见,编号为2的任务进度条已经从原有位置向上偏移了两行。
复现代码片段:
with tqdm( total=total, unit="B", unit_scale=True, unit_divisor=1024, leave=True, ncols=100, colour="green", position=index, dynamic_ncols=True, desc=f"{index}", ) as progress_bar, open(filelocation, "wb") as f: for chunk in r.iter_content(1024): progress_bar.update(len(chunk)) if chunk: f.write(chunk)
解决方法
错位的核心原因很明确:bash默认开启onlcr配置,会将输出的换行符自动转换为回车+换行,导致tqdm内部计算的光标移动行数和终端实际行位置出现偏差;再加上多线程场景下每个进度条独立退出时会单独发送光标移动指令,很容易出现位置计算不同步的问题。
可按优先级选择以下方案修复:
- 运行脚本前先在bash执行
stty -onlcr关闭换行自动映射,从根源消除行计数偏差,不需要修改原有代码 - 不要让子线程里的tqdm在with块退出时自动关闭,所有子线程任务执行完成后,回到主线程统一遍历所有进度条对象按顺序调用
.close(),避免多线程同时发送终端控制指令导致的冲突 - 嫌手动管理position和关闭逻辑麻烦的话,直接用tqdm自带的多线程封装
tqdm.contrib.concurrent.thread_map执行下载任务,内部已经处理了多线程下的光标同步、位置分配逻辑,不需要手动传position参数 - 如果不需要在任务完成后保留进度条,直接把tqdm初始化参数里的
leave设为False,任务完成后进度条会自动清空,不会出现残留错位的问题
内容的提问来源于stack exchange,提问作者Jithin Johnson
相关产品推荐
相关产品推荐

