2

我有一个需要几分钟才能运行的 tcl 脚本(执行时间因配置不同而异)。

我希望用户对它是否仍在执行以及脚本执行时完成需要多长时间有所了解。

到目前为止我的一些想法:

1)使用 ... 表示它随着每个内部命令运行左右而不断增加。但同样,它并没有真正让第一次使用的用户知道还有多少。

2)使用我在很多地方看到的旋转斜线。

3) 在屏幕上显示实际完成百分比输出。不知道这是否可行或如何去做。

有没有人对可以做什么有任何想法,以便脚本的用户了解正在发生的事情以及如何做到这一点?

此外,如果我使用 ... 来实现它,我如何让他们打印 . 每次都在同一行。如果我在 tcl 脚本中使用 puts 来执行此操作,则 . 只是打印在下一行。

对于旋转斜线,我需要替换已经打印在屏幕上的东西。我怎么能用 tcl 做到这一点?

4

2 回答 2

2

首先,您在打印点时遇到问题的原因是 Tcl 正在缓冲其输出,等待新行。这通常是一种有用的行为(通常足以使其成为默认行为)但在这种情况下不需要它,因此您可以使用以下命令将其关闭:

fconfigure stdout -buffering none

(其他缓冲选项是linefull,它们提供逐渐更高级别的缓冲以提高性能但降低响应能力。)或者,flush stdout在打印一个点之后执行。(或者将点打印到stderr,默认情况下是无缓冲的,因为主要用于错误消息。)

做一个微调器并不比打印点难多少。关键技巧是使用回车(一个不可打印的字符,有时可视为^M)将光标位置移回行首。将微调器代码分解为一个小过程很好:

proc spinner {} {
    global spinnerIdx
    if {[incr spinnerIdx] > 3} {
        set spinnerIdx 0
    }
    set spinnerChars {/ - \\ |}
    puts -nonewline "\r[lindex $spinnerChars $spinnerIdx]"
    flush stdout
}

然后你需要做的就是spinner定期打电话。简单的!(另外,完成后在微调器上打印一些东西;只需这样做puts "\r$theOrdinaryMessage"。)

一直到一个实际的进度表是很好的,它建立在这些技术的基础上,但它需要你计算出有多少处理要做等等。微调器更容易实现!(特别是如果你还没有确定有多少工作要做。)

于 2012-12-12T10:07:02.017 回答
1

标准输出流最初是行缓冲的,因此在您写入换行符、调用刷新或关闭它(当您的脚本退出时自动完成)之前,您不会看到新的输出。您可以使用...关闭此缓冲

fconfigure stdout -buffering none

...但是诊断、错误、消息、进度等确实应该写入stderr流。它默认将缓冲设置为无,因此您不需要 fconfigure。

于 2012-12-12T10:10:56.980 回答