在TCL catch命令中捕获标准输出

问题描述

在我的主要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