我需要从Tcl中长时间运行的外部程序中收集输出。我不能使用exec,因为这会阻塞直到其他程序完成。所以,我想我应该打开一个烟斗:
set pipe [open "|long_running_program" "r"]
但是我不清楚如何将输出发送到stdout。我使用纯Tcl,没有事件循环,所以我不能使用fileevent。
答案 0 :(得分:2)
您应该做的是将管道置于非阻塞模式。然后,您可以使用read
获取管道上当前可用的所有内容,准备好转移到stdout。但是,你需要弄清楚何时自己寻找输出; fileevent
命令是Tcl的解决方案,但这需要使用事件循环。 (当然,您可以通过update
或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扩展包。