2016-06-24 30 views
2

我試圖在使用TCL執行外部程序時實現重試機制。試圖將STDIN提供給外部程序時遇到一些問題。我現在正在用一個簡化的例子來解決這個問題。以下面的python腳本(simple.py):TCL - 將STDIN餵給exec

x = raw_input() 
y = raw_input() 
print x + y 

從輸出中輸入2個字符串將是字符串的連接結果。

現在從TCL解釋以下命令作品:

% exec python stuff.py << 1\n2 
12 

但是當我嘗試它在單獨的命令拆分,或者他們在此之前添加一個字符串,它失敗。

失敗1:

% set cmd "python simple.py << 1\n2" 
% exec $cmd 
couldn't execute "python simple.py << 1 
2": no such file or directory 

故障2:

% set cmd1 "python simple.py" 
% set cmd2 "1\n2" 
% exec $cmd1 << $cmd2 

無法執行 「蟒simple.py」:沒有這樣的文件或目錄

故障3:

% set fullCommandString "exec python simple.py << 1\n2" 
% eval $fullCommandString 
Traceback (most recent call last): 
    File "simple.py", line 2, in <module> 
    y = raw_input() 
EOFError: EOF when reading a line 

第三種情況似乎啓動腳本,但它將STDIN的兩行解釋爲一行。

任何幫助表示讚賞。

回答

2

默認情況下,Tcl的命令不會在參數中重新解釋空白。 exec就是其中之一,它遵循相同的規則。這意味着您需要告訴Tcl將單詞列表解釋爲單詞列表,否則它只是一個字符串。幸運的是,這裏有{*};擴展運算符語法將該單詞的其餘部分解釋爲Tcl列表,並在您編寫它的位置使用該列表中的單詞。我發現它非常有用。

解決最簡單的其實是你的第二個案例:

% set cmd1 "python simple.py" 
% set cmd2 "1\n2" 
% exec {*}$cmd1 << $cmd2 

您可以通過添加Tcl的報價單,以確保1\n2仍然解釋爲一個字(否則換行是一個固定第一和第三完全合理的列表項分隔符)。

% set cmd "python simple.py << {1\n2}" 
% exec $cmd 
% set fullCommandString "exec python simple.py << {1\n2}" 
% eval $fullCommandString 

第三,可以更經濟,雖然寫的:

% set fullCommandString "exec python simple.py << {1\n2}" 
% {*}$fullCommandString 

作爲一個經驗法則,如果你在現代的Tcl(注:見evalnamespace evalinterp evaluplevel),那麼它通常表明某些代碼可以變得更高效並且通過切換到使用exp來減少錯誤安靜。


TL;博士:{*}$cmd1之前在你的第二個例子,以獲得地道的修復。