TCL/TK - 如何捕获包中的 stderr 输出?
TCL/TK - how does one capture stderr output from a package?
我有一个应用程序使用了一些包。查看他们的源代码,我发现他们正在做一个简单的 puts stderr ...
来转储调试信息。问题是如果你用 FreeWrap 或 TDK 之类的东西包装程序,你将无法访问控制台;所以我们想将该 stderr 输出转发到一个文件,以便我们可以看到正在打印的内容。
我在 Whosebug 的某个地方看到,您可以简单地关闭 stderr
频道,打开一个新频道,它应该会自动替换最近关闭的频道,如下所示:
close stderr
set out [open "outfile.txt" w]
puts stderr "hello world" # should output to the file
不幸的是,这不起作用。当我尝试时,我收到错误消息:can not find channel named "stderr"
您可以重写 puts
以便可以截获到 stderr 的打印:
set error_file [open "outfile.txt" w]
rename puts __tcl__puts
proc puts {args} {
if {[llength $args] == 2 && [lindex $args 0] eq "stderr"} {
set args [list $::error_file [lindex $args end]]
}
__tcl__puts {*}$args
}
这个问题已经解决了很多次:使用通道拦截器(之前介绍过,):
通道拦截器实现为通道转换; here 之前已经介绍过。
第 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's。
第 2 步:在您的打印代码
周围使用 stderr
注册拦截器
set cs [ChannelSink new]
chan push stderr $cs
puts stderr "hello world"
chan pop stderr
我有一个应用程序使用了一些包。查看他们的源代码,我发现他们正在做一个简单的 puts stderr ...
来转储调试信息。问题是如果你用 FreeWrap 或 TDK 之类的东西包装程序,你将无法访问控制台;所以我们想将该 stderr 输出转发到一个文件,以便我们可以看到正在打印的内容。
我在 Whosebug 的某个地方看到,您可以简单地关闭 stderr
频道,打开一个新频道,它应该会自动替换最近关闭的频道,如下所示:
close stderr
set out [open "outfile.txt" w]
puts stderr "hello world" # should output to the file
不幸的是,这不起作用。当我尝试时,我收到错误消息:can not find channel named "stderr"
您可以重写 puts
以便可以截获到 stderr 的打印:
set error_file [open "outfile.txt" w]
rename puts __tcl__puts
proc puts {args} {
if {[llength $args] == 2 && [lindex $args 0] eq "stderr"} {
set args [list $::error_file [lindex $args end]]
}
__tcl__puts {*}$args
}
这个问题已经解决了很多次:使用通道拦截器(之前介绍过,
通道拦截器实现为通道转换; here 之前已经介绍过。
第 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's。
第 2 步:在您的打印代码
周围使用stderr
注册拦截器
set cs [ChannelSink new]
chan push stderr $cs
puts stderr "hello world"
chan pop stderr