我需要从 Tcl 中长时间运行的外部程序收集输出。我不能使用 exec,因为这会阻塞,直到其他程序完成。所以,我想我应该打开一个管道:
set pipe [open "|long_running_program" "r"]
但是我不清楚如何将输出发送到标准输出。我使用的是纯 Tcl,没有事件循环,所以我不能使用 fileevent。
我需要从 Tcl 中长时间运行的外部程序收集输出。我不能使用 exec,因为这会阻塞,直到其他程序完成。所以,我想我应该打开一个管道:
set pipe [open "|long_running_program" "r"]
但是我不清楚如何将输出发送到标准输出。我使用的是纯 Tcl,没有事件循环,所以我不能使用 fileevent。
您应该做的是将管道置于非阻塞模式。然后,您可以使用read
获取管道上当前可用的所有内容,准备传输到标准输出。但是,您需要自己弄清楚何时寻找输出;该fileevent
命令是 Tcl 的解决方案,但这需要使用事件循环。update
(当然,您可以通过or启动一个临时vwait
的;使用 tclsh 并不意味着没有事件循环,而只是意味着没有默认的事件循环。)
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
}
您还应该知道,许多程序仅在写入管道时才以突发方式传递数据。他们根据是写入管道还是终端来改变他们的行为。这可能很重要,特别是如果您正在执行命令自动化;如果它对你有用,你最好的选择是 Expect 扩展包。