tcl停止所有输出到stdout通道?

时间:2012-07-03 09:16:47

标签: tcl stdout

我正在运行一堆函数。他们每个都向stdout输出大量文本,这阻止我快速检查结果。 有没有简单的方法来阻止输出到stdout频道? 感谢

2 个答案:

答案 0 :(得分:2)

如果这些函数只是为了记录而写入stdout并且你想抛弃所有这些东西,他们不想写入磁盘或套接字或任何其他类型的通道,最简单的方法是:

rename puts original_puts
proc puts args {}   ;# A do-nothing procedure!

要转换回正常操作:

rename puts {}
rename original_puts puts

请注意,如果包装的代码中包含错误,这将导致问题,除非您小心。这是一个包装好的“仔细”版本(对于Tcl 8.5):

proc replacement_puts args {}
proc silentEval {script} {
    rename puts original_puts
    interp alias {} puts {} replacement_puts
    catch [list uplevel 1 $script] msg opts
    rename puts {}
    rename original_puts puts
    return -options $opts $msg
}

然后你就这样做了:

silentEval {
    call-noisy-function-A
    call-noisy-function-B
    ...
}

如果您有想要写入文件(或套接字或......)的代码,那么可以通过更复杂的replacement_puts(可以始终使用original_puts来执行脏工作)

如果这些函数从C级写入stdout,那么你就会陷入困境。您可以close stdout;open /dev/null将文件描述符定向到接收器,但是您无法轻松地从中恢复。 (如果有必要,可以在TclX包中找到dup。如果可以,请尝试上面的简单版本。

答案 1 :(得分:0)

阻止输出到stdout / stderr的唯一好方法是删除(以某种方式) 您正在执行脚本的解释器中的stdout / stderr通道,因为有很多方法可以将内容写入通道(包括但不限于putschan putsfcopy

我建议创建一个新的安全interp并将频道传输到此interp,调用脚本,然后将频道传回。之后,您可以选择删除interp或将其重新用于类似目的。

proc silentEval {script} {
    set i [interp create -safe]
    interp transfer {} stdout $i
    catch [list uplevel 1 $script] msg opts
    interp transfer $i stdout {}
    interp delete $i
    dict incr $opts -level
    return -options $opts $msg
}