Tcl输出从stdout到文件的重定向

时间:2014-12-08 00:53:32

标签: tcl tclsh

我知道这个问题在这里被多次询问过。我查看了回复,但无法弄清楚它的工作方式。请你帮我理解。

这就是:

我试图在tclsh命令行上输入一个tcl脚本,我想将该脚本的输出重定向到一个文件中。

$ source my_script.tcl

脚本my_script.tcl是这样的:

set output_file final_result
set OUT [open $output_file w]

proc calculate{} { 
    <commands> 
    return $result
}

foreach value [calculate] { 
    puts $output_file "$value"
}

这个脚本仍然将输出抛出到stdout上,而我希望它将输出重定向到指定为&#34; final_result&#34;

你能帮我理解我哪里出错吗?

2 个答案:

答案 0 :(得分:1)

正如您在此处所述,您的程序看起来还不错(除了一些明显的小问题)。您的问题是calculate必须写入stdout,而是需要返回一个值。或者你的案例中的值列表,实际上(因为你通过foreach填充它们)。

因此,如果你这样做:

proc calculate {} {
    set result {}
    puts [expr {1 + 2 * 3}]
    return $result
}

然后你将获得输出写入stdout和空final_result(因为它是一个空列表)。如果您将其更改为:

proc calculate {} {
    set result {}
    lappend result [expr {1 + 2 * 3}]
    return $result
}

然后您的代码将按预期执行。也就是说,从putslappend result 我建议您这样做。


您可以通过覆盖puts来捕获“stdout”。这是一个黑客!

rename puts _puts
proc puts {args} {
    # Detect where we're running. IMPORTANT!
    if {[info level] > 1 && [lindex [info level -1] 0] eq "calculate"} {
        upvar 1 result r
        lappend r [lindex $args end]
    } else {
        _puts {*}$args
    }
    return
}

我不相信检测是否捕获值的代码应该是它应该是什么,但它在非正式测试中起作用。 (它也有可能通过一些技巧捕获stdout本身,但最不可怕的是 - 拦截频道的堆叠“转换” - 需要更多的代码......而其他替代方案在微妙方面更糟糕。)

答案 1 :(得分:0)

假设计算不写入stdout,@ DonalFellows指出并建议的所有其他好东西已经完成......

您需要将主脚本中的放置更改为

puts $OUT "$value"

发布的脚本写入名为final_result的频道,几乎肯定不存在。我希望puts循环中的foreach语句出错。

不要忘记关闭输出文件 - 要么退出tclsh解释器,要么最好通过执行

close $OUT

在检查其中的任何内容之前,