TCL-获取执行进程的日志

标签 tcl

目前我正在执行以下命令

set pid [exec make &]

set term_id [wait pid]

第一个命令将在TCL内部执行makefile,第二个命令将等待第一个命令的makefile操作完成。 第一个命令在标准输出上显示 makefile 的所有日志。当使用重定向或任何其他方法在 exec 的最后一个参数中给出“&”时,是否可以将所有日志存储在变量或文件中?

如果未给出“&”,那么我们可以使用以下命令获取输出:

set log [exec make]

但如果给出“&”,则命令将返回进程 ID,

set pid [exec make &]

那么是否可以停止 stdout 日志并将它们放入变量中?

最佳答案

如果您使用的是 Tcl 8.6,则可以使用以下命令捕获输出:

lassign [chan pipe] reader writer
set pid [exec make >@$writer &]
close $writer

不要忘记从 $reader 中读取,否则子进程将停止。请注意,以这种方式使用时,输出将以完全缓冲的方式传递,尽管这在进行交互式工作时更为重要。如果您还希望输出回显为标准输出,则需要让您的脚本执行此操作。这是一个简单的读取器处理程序。

while {[gets $reader line] >= 0} {
    lappend log $line
    puts $line
}
close $reader

在 Tcl 8.6 之前,最好的选择是创建子进程命令管道:

set reader [open |make]

如果您需要 PID,这可能会变得有点复杂:

set reader [open |[list /bin/sh -c {echo $$; exec make}]]
set pid [gets $reader]

是的,这很丑……


[编辑]:您正在 Tcl 8.5 中使用 Tk(因此您需要上面的 open |... 管道形式),因此您希望保持事件循环继续进行。没关系。这正是 fileevent 的用途,但您必须异步思考

# This code assumes that you've opened the pipeline already
fileevent $reader readable [list ReadALine $reader]
proc ReadALine {channel} {
    if {[gets $channel line] >= 0} {
        HandleLine $line
    } else {
        # No line could be read; must be at the end
        close $channel
    }
}
proc HandleLine {line} {
    global log
    lappend log $line;     # Or insert it into the GUI or whatever
    puts $line
}

此示例使用非阻塞 I/O。这可能会导致问题,但也可能不会。如果它确实引起问题,请使用此:

fconfigure $reader -blocking 0
fileevent $reader readable [list ReadALine $reader]
proc ReadALine {channel} {
    if {[gets $channel line] >= 0} {
        HandleLine $line
    } elseif {[eof $channel]} {
        close $channel
    }
}
proc HandleLine {line} {
    global log
    lappend log $line
    puts $line
}

更复杂和通用的版本是可能的,但只有当您处理不受信任的 channel (例如公共(public)服务器套接字)时,它们才是真正必要的。


如果您一直在使用 8.6,您可以使用协程来使此代码看起来更类似于我之前使用的直线代码,但它们是严格的 8.6 功能(后来,一旦我们这样做了)更高版本)仅因为它们依赖于无堆栈执行引擎。

关于TCL-获取执行进程的日志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34989209/

相关文章:

arrays - 重命名全局数组 TCL

c++ - VTK如何平滑一条线

python - tcl 和 Python 的相似之处

shell - 需要从 expect 脚本返回生成进程的退出代码

Python 版本和 Tcl/Tk 兼容性

algorithm - 如何以更接近匹配的方式获得排序列表?

json - TCL 字典转 JSON

shell - 当我的 tcl 脚本运行时,在屏幕上打印完成的百分比?

tcl - catch "Tcl Interpreter Error"

tcl - 列表在 Tcl 中不包含自己的成员