首页 > 解决方案 > TCL/TK - 如何从包中捕获标准错误输出?

问题描述

我有一个使用一些包的应用程序。查看他们的源代码,我发现他们正在做一个简单puts stderr ...的转储调试信息的工作。问题是,如果您使用 FreeWrap 或 TDK 之类的东西包装程序,您将无法访问控制台;所以我们想将该标准错误输出转发到一个文件,以便我们可以看到正在打印的内容。

我在 StackOverflow 上的某个地方看到您可以简单地关闭stderr频道,打开一个新频道,它应该会自动替换最近关闭的频道,如下所示:

close stderr
set out [open "outfile.txt" w]

puts stderr "hello world" # should output to the file 

不幸的是,这不起作用。当我尝试它时,我收到错误消息:can not find channel named "stderr"

标签: redirectpackagetcltkstderr

解决方案


这已多次解决:使用通道拦截器(之前介绍过,用于捕获 Tcl 测试套件输出):

通道拦截器被实现为通道变换;并且之前已经在这里介绍过。

第 1 步:定义通道拦截器

oo::class create ChannelSink {
    variable fileHandle
    method initialize {handle mode} {
        set fileHandle [open "outfile.txt" w]
        fconfigure $fileHandle -translation binary
        return {finalize initialize write}
    }
    method finalize {handle} {
        catch {close $fileHandle}
    }

    method write {handle bytes} {
        puts -nonewline $fileHandle $bytes 
        return
    }
}

上面的代码片段来自Donal 的.

stderr第 2 步:在您的打印代码周围注册拦截器

set cs [ChannelSink new]
chan push stderr $cs

puts stderr "hello world"

chan pop stderr

推荐阅读