在没有fileevent的情况下,如何将长时间运行的程序的输出发送到tcl中的stdout?

在没有fileevent的情况下,如何将长时间运行的程序的输出发送到tcl中的stdout?,tcl,Tcl,我需要收集Tcl中长期运行的外部程序的输出。我不能使用exec,因为这将阻塞,直到其他程序完成。所以,我想我应该打开一个管道: set pipe [open "|long_running_program" "r"] 但是我不清楚如何将输出发送到stdout。我使用的是纯Tcl,没有事件循环,因此无法使用fileevent。您应该将管道置于非阻塞模式。然后,您可以使用read获取管道上当前可用的所有内容,准备传输到标准输出。然而,您需要自己确定何时寻找输出;fileevent命令是Tcl的解决方

我需要收集Tcl中长期运行的外部程序的输出。我不能使用exec,因为这将阻塞,直到其他程序完成。所以,我想我应该打开一个管道:

set pipe [open "|long_running_program" "r"]

但是我不清楚如何将输出发送到stdout。我使用的是纯Tcl,没有事件循环,因此无法使用fileevent。

您应该将管道置于非阻塞模式。然后,您可以使用
read
获取管道上当前可用的所有内容,准备传输到标准输出。然而,您需要自己确定何时寻找输出;
fileevent
命令是Tcl的解决方案,但这需要使用事件循环。(当然,您可以通过
update
vwait
启动一个临时循环;使用tclsh并不意味着没有事件循环,而只是意味着没有默认的事件循环。)


您还应该知道,许多程序在写入管道时仅以突发方式传输数据。它们会根据是向管道还是向终端写入而改变其行为。这可能很重要,特别是如果你在做指挥自动化;如果对您有帮助,您最好的选择是Expect扩展包。

非常感谢您回答我的问题。代码对我来说不起作用,但正如您所说,这可能是应用程序的本质,我无法控制。但令我惊讶的是,您的代码没有一个循环来重复地将输出发送到stdout。你确定这是正确的吗?在我看来,代码应该更正如下:set pipe[open”| qclean“r”]fconfigure$pipe-阻塞0,而{![eof$pipe]}{如果{[fblocked$pipe]}{{现在没有可用数据,请稍后再试}否则{#打印到标准输出;使用数据puts-nonewline$data}}close$pipe中已有的换行符
fconfigure $pipe -blocking 0

set data [read $pipe]
if {[eof $pipe]} {
    # Other side is finished; close the pipe?
} elseif {[fblocked $pipe]} {
    # No data available right now; try later
} else {
    # Print to stdout; use the newlines already in the data
    puts -nonewline $data
}