【发布时间】:2021-12-01 00:56:23
【问题描述】:
有没有办法获得可用的 tcl 频道列表?我正在使用内置 tcl 解释器的第三方工具,所以在我执行close stdout 之后,它仍然会将输出打印到提示符。
怀疑它正在使用另一个通道,因为关闭标准输出后,我尝试了puts "hello",它给出了一个错误找不到名为标准输出的通道
TIA
【问题讨论】:
有没有办法获得可用的 tcl 频道列表?我正在使用内置 tcl 解释器的第三方工具,所以在我执行close stdout 之后,它仍然会将输出打印到提示符。
怀疑它正在使用另一个通道,因为关闭标准输出后,我尝试了puts "hello",它给出了一个错误找不到名为标准输出的通道
TIA
【问题讨论】:
Tcl 解释器可以覆盖puts 命令,这样即使您执行close stdout,它也可以写入类似标准输出的内容。它甚至相当容易做到(如果您在子解释器中运行并且puts 是父解释器中的别名)。唯一的原因是puts 的参数模式不适合过程如何将参数映射到形式参数。这是一个错误的版本——它缺少很多解析代码——但很接近。
proc magicPuts {interp args} {
if {[llength $args] == 1} {
puts [lindex $args 0]
} else {
$interp invokehidden puts {*}$args
}
}
set subinterp [interp create]
interp hide $subinterp puts
interp alias $subinterp puts {} magicPuts $subinterp
interp share {} stdout $subinterp
$subinterp eval { source yourscript.tcl }
【讨论】:
请注意,口译员可能会共享频道。考虑以下代码:
interp create foo
interp share {} stdout foo
close stdout
chan names; # stdin stderr
puts hello; # can not find channel named "stdout"
foo eval {puts hello}; # hello
因此,即使标准输出已在一个解释器中关闭,其他解释器仍然可以使用它。
事实上,甚至没有必要与从解释器显式共享标准输出,除非它被创建为安全解释器。标准 I/O 通道会自动与常规解释器共享。
如果没有关于第三方工具内部工作原理的更多信息,很难确定发生了什么。
【讨论】:
interp slaves 命令看到他们的孩子以及更远的地方。
interp 了解更多详情
chan names ?pattern? 将返回开放频道列表,可选择匹配模式。
【讨论】: