运行耗时命令时,如何创建CLI进度条?
嗨,这个问题我太熟了!处理耗时CLI命令时,加个进度提示不仅能避免你慌慌张张以为程序挂了,还能大概掌握进度节奏,下面分享几个实用的实现思路,附代码示例:
几种常见的CLI进度提示实现方法
1. 动态刷新的状态字符(适合未知总进度的场景)
如果你的任务没法预估总步骤(比如调用一个不知道内部逻辑的耗时命令),最简单的方式是用动态变化的字符来提示“程序还在跑”,比如转圈的光标或者持续打点。
Bash 示例:
#!/bin/bash echo "启动耗时任务..." # 把你的耗时命令放这里,比如用sleep模拟10分钟任务 sleep 600 & PID=$! # 定义转圈的字符序列 spin='-\|/' i=0 # 循环检查进程是否存活 while kill -0 $PID 2>/dev/null; do i=$(( (i+1) % 4 )) # 用\r回到行首,覆盖之前的输出 printf "\r${spin:$i:1} 运行中,请稍候..." sleep 0.5 done # 任务完成后清除进度提示,显示完成信息 printf "\r✅ 任务执行完成!\n"
2. 百分比进度条(适合已知总步骤/数据量的场景)
如果能明确任务的总步骤(比如处理100个文件、遍历1000条数据),可以做一个直观的百分比进度条,让你清楚看到完成度。
Python 示例:
import sys import time def update_progress(total, current): # 计算完成百分比 percent = (current / total) * 100 # 进度条长度可自定义 bar_length = 50 filled = int(bar_length * current // total) # 拼接进度条字符串 bar = '=' * filled + '-' * (bar_length - filled) # 用\r覆盖当前行,flush强制刷新缓冲区 sys.stdout.write(f"\r[{bar}] {percent:.1f}% 已完成") sys.stdout.flush() # 模拟10分钟任务:120个步骤,每个步骤耗时5秒 total_steps = 120 for step in range(total_steps + 1): update_progress(total_steps, step) time.sleep(5) # 任务完成后换行显示结果 print("\n✅ 所有任务执行完毕!")
3. 用现成工具/库(省心首选)
不想自己造轮子?很多现成的工具和库能帮你快速实现漂亮的进度提示,还带剩余时间、速度统计等功能。
Python 用tqdm库:
tqdm是Python生态里最流行的进度条库,一行代码就能搞定:
from tqdm import tqdm import time # 模拟10分钟任务,120个步骤 for _ in tqdm(range(120), desc="正在处理"): time.sleep(5) print("\n✅ 任务完成!")
运行后会显示带颜色的进度条,还实时更新预计剩余时间,非常直观。
Bash 用pv命令:
如果是处理数据流(比如复制大文件、解压、转码),pv命令堪称神器,它会自动显示进度、传输速度、剩余时间:
# 复制大文件并显示进度 pv large_backup.tar.gz > /mnt/external_drive/large_backup.tar.gz
大部分Linux发行版默认安装了pv,如果没有可以用apt install pv或yum install pv安装。
4. 自定义状态提示(显示具体处理内容)
如果任务是处理多个条目(比如批量压缩文件、批量下载),可以实时显示当前处理的内容,让进度更透明:
Bash 示例:
#!/bin/bash # 模拟需要处理的大文件列表 files=(video1.mp4 video2.mp4 video3.mp4 video4.mp4 video5.mp4) total_files=${#files[@]} for index in "${!files[@]}"; do current_file=${files[$index]} current_num=$((index + 1)) percent=$(( current_num * 100 / total_files )) # 实时显示当前处理的文件和进度 printf "\r正在处理第 %d/%d 个文件:%s (%d%%)" $current_num $total_files "$current_file" $percent # 这里替换成你的耗时处理命令,比如压缩 ffmpeg -i "$current_file" -c:v libx265 "${current_file%.mp4}_compressed.mp4" > /dev/null 2>&1 done printf "\r✅ 所有文件处理完成!\n"
内容的提问来源于stack exchange,提问作者yael
相关产品推荐
相关产品推荐

