Python实现固定在stdout顶部的粘性进度条
Python实现固定顶部的进度条(类似apt升级效果)
需求说明:实现进度条固定在终端顶部,下方内容逐行打印时,进度条始终保持在顶部位置不被挤走,类似Linux下apt upgrade的交互逻辑(注:实际apt进度条在底部,此处需求为进度条固定顶部)。
期望效果示例
Setting up python3-aiodns (3.0.0-2) ... Setting up libpython3-all-dev:arm64 (3.11.2-1+b1) ... Setting up python3-dev (3.11.2-1+b1) ... Setting up theharvester (4.2.0-0kali2) ... Setting up faraday (4.3.5-0kali1) ... faraday.service is a disabled or a static unit not running, not starting it. Setting up samba-common-bin (2:4.17.7+dfsg-1) ... Setting up python3-aesedb (0.1.3+git20230221.9b7c468-0kali1) ... Setting up samba (2:4.17.7+dfsg-1) ... nmbd.service is a disabled or a static unit not running, not starting it. samba-ad-dc.service is a disabled or a static unit not running, not starting it. smbd.service is a disabled or a static unit not running, not starting it. Setting up python3-all-dev (3.11.2-1+b1) ... Setting up kali-linux-headless (2023.2.5) ... Setting up python3-pypykatz (0.6.6-0kali1) ... Setting up kali-linux-default (2023.2.5) ... Processing triggers for systemd (252.6-1) ... Processing triggers for man-db (2.11.2-2) ... Progress: [ 99%] [#########################################################.]
用户尝试的代码
import time def print_progress_bar(iteration, total): percent = "{:.1f}".format(100 * (iteration / float(total))) filled_length = int(50 * iteration // total) bar = "█" * filled_length + "-" * (50 - filled_length) print(f"\033[F\033[KProgress: |{bar}| {percent}% Complete") for i in range(1, 101): print_progress_bar(i, 100) print(i, end=" ") time.sleep(0.1)
问题分析
这段代码的核心问题在于:
- 使用
\033[F回到上一行时会覆盖之前打印的内容,无法保留历史输出 print(i, end=" ")设置了不换行,导致内容无法逐行展示
解决方案
利用终端ANSI控制码实现光标位置的保存、恢复和行操作,确保进度条始终停留在顶部,内容在下方逐行打印:
import time def update_top_progress(iteration, total): # 计算进度参数 percent = "{:.1f}".format(100 * (iteration / float(total))) filled_length = int(50 * iteration // total) bar = "█" * filled_length + "-" * (50 - filled_length) # 保存当前光标位置,避免更新进度条时丢失内容输出位置 print("\033[s", end="") # 移动光标到终端第一行开头(进度条固定位置) print("\033[1;1H", end="") # 清空当前行内容,避免进度条残留旧数据 print("\033[K", end="") # 打印更新后的进度条 print(f"Progress: |{bar}| {percent}% Complete") # 恢复之前保存的光标位置,回到内容输出区域继续打印 print("\033[u", end="") # 初始化顶部进度条 print("Progress: |--------------------------------------------------| 0.0% Complete") # 换行到内容输出区域 print() # 模拟业务内容逐行输出+进度条更新 for i in range(1, 101): update_top_progress(i, 100) # 打印实际业务内容,逐行展示 print(f"Setting up package-{i} ... Processing") time.sleep(0.1)
关键控制码说明
\033[s:保存当前光标位置\033[1;1H:将光标移动到终端第一行的开头\033[K:清空当前行的所有内容\033[u:恢复之前保存的光标位置
内容的提问来源于stack exchange,提问作者federikowsky
相关产品推荐
相关产品推荐

