问题描述
在我的主要tcl脚本中,我正在调用包装在catch命令中的tcl proc。 该proc依次调用了10个proc。
在这10个过程中的任何一个过程中执行均发生错误时,TCL仍将按预期继续执行我的主脚本,并且我仅能查看捕获的错误消息。该错误消息可能有/没有一定结论性,无法确定执行过程中出错的10个过程中的哪个。
有没有办法继续捕获所有stdout直到出现错误点? 我知道可以通过将这10个proc中的所有消息(puts语句)写入另一个日志文件来完成。但是我有兴趣知道是否还有其他方法。
解决方法
catch
命令根本不会拦截I / O。要截获输出,最简单也是大多数方法是使用chan push
在该通道上放置一个channel transform。
oo::class create Capture {
variable contents encoding
# Implement the channel interception protocol
method initialize {handle mode} {
set contents {}
return {initialize finalize write}
}
method finalize handle {
# We do nothing here
}
method write {handle buffer} {
append contents $buffer
return $buffer
}
# Methods for ordinary people!
method capture {channel body} {
set encoding [chan configure $channel -encoding]
chan push $channel [self]
try {
uplevel 1 $body
} finally {
chan pop $channel
}
}
method contents {} {
# Careful; need the encoding as channels work with binary data
return [encoding convertfrom $encoding $contents]
}
}
如何使用此类:
set capt [Capture new]
$capt capture stdout {
puts "Hello world!"
}
puts "Captured [string length [$capt contents]] characters"
puts [lmap c [split [$capt contents] ""] {scan $c "%c"}]
输出(我假设您可以识别ASCII码;最后的13 10
是回车/换行符的顺序):
Hello world!
Captured 14 characters
72 101 108 108 111 32 119 111 114 108 100 33 13 10
,
catch
不会捕获Tcl过程的标准输出,它将捕获返回值。
交互式tclsh中的演示:
% proc p {} {puts "some stdout"; return "return value"}
% catch p result
some stdout
0
% set result
return value