2014-12-08 1124 views
0

我知道這個問題在這裏已經被問了好幾次了。我已經看過答覆,但無法弄清楚它的工作方式。請你幫我理解。Tcl輸出從stdout重定向到一個文件

這裏有雲:

我試圖源tclsh的命令行腳本來執行,我想該腳本的輸出重定向到文件中。

$ 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」

文件

你能幫我理解我出錯的地方嗎?

+0

你知道'計算{}'可能不是你想說的嗎? Tcl中的空間很重要。 – 2014-12-08 01:38:34

回答

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捕捉「標準輸出」。這是一個黑客!

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 
} 

我不相信檢測是否捕獲值的代碼是它應該是什麼,但它在非正式測試中起作用。 (也可以通過一些技巧來捕獲標準輸出本身,但最不可怕的是 - 攔截該通道的堆棧式「轉換」 - 需要更多的代碼...而其他選擇在細節方面更糟糕。)

+0

謝謝!我的proc中已經包含lappend語句,但我仍然看到相同的空文件。你能提出任何解決方法嗎? – user3641866 2014-12-08 02:38:43

+0

關閉'stdout'並打開其他通道可能會起作用。根據一些瘋狂的東西,像其他interp在該線程... – 2014-12-08 03:40:13

0

假設計算不寫入stdout,和所有其他的好東西指出並@DonalFellows已完成建議...

您需要在主腳本看跌期權改爲

puts $OUT "$value" 

發佈的腳本寫入名爲final_result的通道幾乎肯定不存在。我期望foreach循環內的puts聲明出錯。

不要忘記關閉輸出文件 - 或preferrably通過執行

close $OUT 

無論是從tclsh的解釋退出您檢查任何東西之前,

+0

謝謝Donal研究員,nurdglaw。我意識到我的腳本有一個破壞的「exec」管道,導致錯誤。我解決了它,現在我的腳本工作正常。感謝所有的幫助! – user3641866 2014-12-16 18:13:44