2010-08-23 78 views
4

我發現tcl exec命令從stdout先返回stderr,然後是stderr。例如,我下面的「測試腳本」的順序生成消息:tcl exec首先讀取stdout然後stderr?

puts "test started" 
puts stderr "some non-fatal error goes to stderr" 
puts "test passed" 

然後我執行這個腳本是這樣的:

set ret [ catch { exec sh -c $cmd } msg ] 

和我從$味精得到的是:

test started 
test passed 
some non-fatal error goes to stderr 

這真的讓我很難得到正確的結果。

有人可以讓如果知道是否有可能獲得爲了從兩個輸出和錯誤消息,並且:

1)請不要重定向這樣的,這可以讓他們一切爲了確實:

set ret [ catch {exec $cmd >&log.txt} msg ] 

2)我有打電話給 TCL腳本 TCL腳本,對不起

3)我也不能直接源.tcl測試腳本becau如果我的tcl腳本只是源 tcl腳本,那麼在這兩者之間就會調用其他腳本。

我使用tclsh的8.3

不知道這是否是太奢侈了。我希望有人可以弄清楚這一點。謝謝。

+1

有關更多提示,請參閱http://wiki.tcl.tk/stderr。 – 2010-08-23 14:57:14

回答

5

首先,讓我們定義一個簡單的命令進行測試的目的,我們可以肯定的意志測試正是我們所需要:

set cmd "echo a; echo b >&2; echo c" 

接下來,我們使用一些額外的幫助來處理輸出和錯誤流的合併(幾行爲清楚起見拆分命令只有這樣,我們能看到的catch包裝物上,並在包裹exec是):

set ret [catch { 
    exec sh -c $cmd |& cat 
} msg] 

如果我們測試,我們會發現,我們得到$ret0,並且$msg正在正確排序:

a 
b 
c 

如何這行得通?訣竅是|&,它在管道到另一個進程時進行合併。 (我們使用cat,因爲它只是傳遞的東西通過無干擾。)

如果您使用的Tcl 8.6(測試版),您可以使用chan pipe產生可以重定向stdoutstderr2>@ fileId form一個通道,但這對你並不有用。 (你知道8.3已經過時了嗎?即使8.4不再被真正支持,8.5是生產級代碼被推薦的目標。)

+0

如果你用'open'做了一個管道,你會有更多的選擇,但是這樣更加複雜。 – 2010-08-23 12:16:25

+0

真棒!涼!!雖然不太清楚機制,但我很高興看到您的文章並使用此代碼。謝謝! – 2010-08-24 01:04:24

+0

機制是「'&'發送stdout和stderr到管道中的下一個進程」。我使用'cat'來傳遞它。 – 2010-08-24 07:06:02

-1

使用source命令,而不是exec只要你想從另一個TCL腳本中調用Tcl腳本:

set ret [catch {source $cmd} msg] 
+0

謝謝ardsrk。但是很抱歉,調用是這樣的:我的tcl腳本調用 - >一個.sh shell文件,它設置系統變量和調用 - > tcl測試腳本。如果我只是源代碼.tcl腳本,它將無法正常工作。 – 2010-08-23 07:28:14

+0

我修改了我的問題以表明清楚。我應該。 – 2010-08-23 07:34:32

相關問題