终端输出样式和格式的最佳实践

82 阅读3分钟

在编写终端脚本时,如何格式化控制台输出?这里所说的输出是指应用程序运行期间产生的输出(日志、标准输出)。

huake_00183_.jpg 我们有一个 Python 脚本,它接收数据,处理数据,更新数据库中的相关数据,并输出进度。我们可以用各种方式设置输出样式:

************ Starting programm X ************
Fetching 450 lands... Done
540 local lands found
syncronizing [--------                ] 10%
Done

输出使用大写字母还是小写字母?是否对输出应用缩进?可以使用破折号或井号等视觉效果吗?是否使用类似 wget 中的进度条?

我们知道这是一种设计,但在 Web 中我们有一些基本规则,我们有可用性,但在控制台输出中没有规则。雅各布·尼尔森对控制台脚本的输出有什么看法?

2、解决方案

可用性即使在控制台脚本中也很重要。特别是对于任何长时间运行的进程,无论 UI 是图形化的还是在终端中,都最好以某种方式显示任务的进度,以提高可用性。我们建议参考尼尔森的启发式法则,他列举了许多原则直接适用于控制台输出。在讨论控制台输出时,有三个启发式法则可能很有用:

  • 系统状态的可见性:通过某种进度条在控制台中显示进度,以便在合理的时间内显示正在进行的操作。
  • 一致性和标准:你在问题中提到了这一点,破折号或井号。
  • 美观和简约的设计:尝试输出最少相关且有用的信息。

对于标准和一致性,请遵循现有流行命令的约定。有两个很好的参考项是 wget 和 pv。它们的进度条看起来非常相似:

wget

44% [================>                      ] 441,017,992  111MB/s  eta 6s

pv

 138MB 0:00:01 [ 107MB/s] [=========================================>] 100%  

它们看起来基本上是一样的。它们还遵循简约设计,在一行中以文本和条形形式表示完成百分比、速度、已完成的字节数以及预计到达时间或已用时间。

在合理的时间内更新方面,我们倾向于每 0.1 秒在控制台中更新一次状态。要让界面感觉响应迅速,你需要一个与此范围相近的值。wget 似乎每 0.2 秒更新一次。但 watch 命令的默认值为 2 秒,感觉太慢了。我们通常最终会将该命令作为 watch -n 0.1 命令运行,以获得 0.1 秒的更新间隔。

其中一条评论指出你的输出应该是可解析且可管道传输的。如果可能,这是一个非常好的特性。我们尤其喜欢 wget 处理此问题的方式。如果你在终端中运行 wget,它将使用条形进度指示器,但如果你将其管道传输到文件或另一个程序,它将使用点进度指示器。它会自动检测你是否有 tty 或正在管道传输命令,并选择最合适的格式。你可以在它的 man 页面中“--progress”参数的文档下阅读相关内容。从本质上讲,它有一个更具人类可读性的输出,另一个更适合机器读取且对日志更友好的输出。

一些相关/有用的链接:

  • 多线程应用程序的 Python 进度条示例
  • Urwid 是一个适用于 Python 的优秀的控制台用户界面库
  • Urwid 中的 ProgressBar 小部件