如何通过 Tcl 脚本在我的 IDE 中获得即时输出?

How to get immediate output in my IDE from a Tcl script?

我刚开始使用tcl语言,我需要创建一个脚本,其中包含每2秒触发的几个函数。我一直在互联网上搜索答案,并找到了几个关于它的主题。例如,我在 StackOverlow (How do I use "after ms script" in TCL?) 上找到了这段代码:

#!/usr/bin/tclsh

proc async {countdown} {
        puts $countdown
        incr countdown -1
        if {$countdown > 0} {
                after 1000 "async $countdown"
        } else {
                after 1000 {puts Blastoff!; exit}
        }
}

async 5

# Don't exit the program and let async requests
# finish.
vwait forever

这段代码可以很容易地适应我想做的事情,但它在我的电脑上不起作用。当我将它复制粘贴到我的 IDE 时,代码会等待几秒钟,然后一次性给出所有输出。 我在网上找到的其他代码也遇到了同样的问题。

如果有人能帮助我就太好了。 非常感谢。

我刚刚将您提供的确切脚本粘贴到 macOS 终端的 tclsh(特别是 8.6)运行ning 中,并且可以正常工作。我预计您的脚本可以在 Tcl 7.6 之后的任何版本上运行,这可以追溯到将近 25 年前。

听起来您的 IDE 以某种方式导致输出被缓冲。在你的 Tcl 脚本中,你可以 probably 通过在 each puts 调用之后放置 flush stdout 或者通过(更容易)将其放在脚本开头的选项:

fconfigure stdout -buffering line
# Or do this if you're using partial line writes:
#      fconfigure stdout -buffering none

问题是 Tcl(与 许多 其他程序一样)检测它的标准输出是去终端还是其他目的地(文件或管道或套接字或...... ).当输出到终端时,它将缓冲模式设置为 line,否则设置为 full。 (相比之下,stderr always 默认情况下具有 none 缓冲,因此无论发生什么错误,都会在崩溃之前解决;没有什么比默认情况下丢失调试信息更糟糕的了。)正在发送大量输出,这无关紧要 — 缓冲区只有几 kB 长,这是一个非常好的性能提升器 — 但当一次只写入非常少量时,这不是您想要的。听起来 IDE 正在做某事(可能使用管道)导致猜测错误。

tcl_interactive 全局变量在形式上是不相关的;这是在没有脚本参数时设置的。即使您将脚本作为参数提供,缓冲规则也适用。)


真正 IDE 修复此问题的正确方法,至少在 POSIX 系统上,是使用虚拟终端 运行 脚本而不是管道。但这是一个复杂得多的话题!