TCL:如何等待一个流直到当前流完成? 我有一个不断更新的日志。 我正在运行一个生成文件的流。此流在后台运行,并且 更新日志,说明[12:23:12:1]\m已成功完成数据\u 01。 一旦我看到这个评论,我就将这个文件用于下一个流。 我创建了一个弹出窗口说等待,直到日志说成功完成,以避免 脚本将转到下一个流并被中止。 但问题是每次我都需要检查日志中的评论和 在弹出窗口中按OK。

TCL:如何等待一个流直到当前流完成? 我有一个不断更新的日志。 我正在运行一个生成文件的流。此流在后台运行,并且 更新日志,说明[12:23:12:1]\m已成功完成数据\u 01。 一旦我看到这个评论,我就将这个文件用于下一个流。 我创建了一个弹出窗口说等待,直到日志说成功完成,以避免 脚本将转到下一个流并被中止。 但问题是每次我都需要检查日志中的评论和 在弹出窗口中按OK。,tcl,Tcl,是否有任何方法可以从更新日志中捕获注释。 我试过了 在这个$行中,我将把它传递给弹出式变量,以便改为说wait-till 已成功完成。我会说成功完成了。 但是,这会引发错误,因为打开的文件太多,而且没有等待。似乎您要做的是监视一个文件,并在不挂起UI的情况下等待将特定行添加到该文件中。为此,您不能在文件上使用异步IO,因为在Tcl中,文件总是可读的。相反,您需要在计时器上轮询文件。在Tcl中,这意味着使用命令。因此,创建一个命令,用于检查文件上次修改的时间,以及自上次检查以来文件是否已更改,然后

是否有任何方法可以从更新日志中捕获注释。 我试过了

在这个$行中,我将把它传递给弹出式变量,以便改为说wait-till 已成功完成。我会说成功完成了。
但是,这会引发错误,因为打开的文件太多,而且没有等待。

似乎您要做的是监视一个文件,并在不挂起UI的情况下等待将特定行添加到该文件中。为此,您不能在文件上使用异步IO,因为在Tcl中,文件总是可读的。相反,您需要在计时器上轮询文件。在Tcl中,这意味着使用命令。因此,创建一个命令,用于检查文件上次修改的时间,以及自上次检查以来文件是否已更改,然后打开文件并查找特定数据。如果数据存在,请设置一些状态变量以允许程序继续执行下一步。如果没有,您只需使用after和适当的间隔安排对check函数的另一个调用


您可以使用如上所述的管道,但应该在通道可用时使用异步IO从通道读取数据。这意味着使用操作系统对一个进程一次可以打开的文件数量有一个限制。通常,如果你接近这个极限,那么你就做错了

让我们后退一点

连续读取日志文件的最简单方法是从程序尾部打开一个管道,并传入-f选项,因此它只报告添加到文件中的内容,而不是每次运行时报告结束。像这样:

set myPipeline [open "|tail -f code.log"]
然后,您可以从这个管道中读取数据,只要您不关闭它,您将只读取一行数据。退出Tcl过程将关闭管道。您可以使用blocking get读取每一行,也可以使用fileevent以便在一行可用时获得回调。后一种形式非常适合GUI

分块形式 回拨表格 假设管道处于阻塞模式。完全非阻塞稍微复杂一些,但遵循类似的模式


这两种形式都调用processFlow,当它出现在日志中时,会使用括号内的行提取位。这就是它不再是通用Tcl的部分…

在这种情况下,流是什么?您使用的是嵌入式版本的Tcl,其中流是一个已知的术语吗?嗨,Bryan,工具相关流。在特定的布局工具流程中,非常感谢Donal:嗨,Donal。我有一个疑问。你能解释一下阻塞形式的{[gets$mypipeline]>=0}和回调形式的{[gets$mypipeline]<0}是什么吗?你的想法很有帮助。非常感谢Patthoyts:。
set myPipeline [open "|tail -f code.log"]
while {[gets $myPipeline line] >= 0} {
    if {[regexp {successfully completed \(([^()]+)\)} $line -> theFlowName]} {
        processFlow $theFlowName
    }
}
close $myPipeline
fileevent $myPipeline readable [list GetOneLine $myPipeline]
proc GetOneLine {pipe} {
    if {[gets $pipe line] < 0} {
        # IMPORTANT! Close upon EOF to remove the callback!
        close $pipe
    } elseif {[regexp {successfully completed \(([^()]+)\)} $line -> theFlowName]} {
        processFlow $theFlowName
    }
}