【问题标题】:Tcl Output redirection from stdout to a file从标准输出到文件的 Tcl 输出重定向
【发布时间】:2014-12-08 00:53:31
【问题描述】:

我知道这个问题已经在这里被问过好几次了。我查看了回复,但无法弄清楚它的工作方式。请您帮助我理解。

这里是:

我正在尝试在 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"
}

这个脚本仍然把输出扔到标准输出上,而我希望它把输出重定向到一个指定为“final_result”的文件中

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

【问题讨论】:

  • 您知道calculate{} 可能不是您想说的吗?空间在 Tcl 中很重要。

标签: tcl tclsh


【解决方案1】:

正如您在此处所描述的,您的程序看起来不错(除了一些明显的小问题)。您的问题是 calculate 必须写入标准输出,而是需要返回一个值。或实际情况下的值列表(因为您通过foreach 填充它们)。

因此,如果您正在这样做:

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

然后你会得到输出写入标准输出和一个空的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 本身,但最不可怕的 - 拦截通道的堆叠“转换” - 需要更多代码......而其他替代方案在微妙之处更糟糕。)

【讨论】:

  • 谢谢!我的 proc 中已经包含了 lappend 语句。但我仍然看到相同的空文件。你能建议任何解决方法吗?
  • 关闭stdout 并打开另一个频道可能会起作用。取决于一些疯狂的东西,比如那个线程中的其他 interp...
【解决方案2】:

假设计算不写入标准输出,并且@DonalFellows 指出和建议的所有其他好东西都已完成......

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

puts $OUT "$value"

发布的脚本写入名为final_result 的频道,该频道几乎可以肯定不存在。我预计 foreach 循环内的 puts 语句会出错。

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

close $OUT

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

【讨论】:

  • 感谢 Donal 研究员,nurdglaw。我意识到我的脚本有一个损坏的“exec”管道导致错误。我解决了它,我的脚本现在可以正常工作了。谢谢大家的帮助!!!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多