2013-01-10 100 views
1

如何調用以bash腳本編寫的外部程序,以便該腳本生成的輸出在sys.stdout中可用,以便我可以記錄通過python輸出到一個文件中。通過Python調用外部程序並將輸出傳遞給標準輸出

例如。我現在請他們通過下面的代碼片段

if os.name == 'nt': 
    path = module_dir_run+'/run.bat' 
else: 
    path = module_dir_run+'/run.sh' 
if os.path.isfile(path): 
    if (splitargs.arg): 
     try: 
      call([path, splitargs.arg]) 
     except: 
      pass 
    else: 
     try: 
      call([path]) 
     except: 
      pass 
else: 
    print "Not found : " + path 

當我存儲sys.stdout = file(filename, "w") IT賣場無論該蟒蛇輸出值,但不是什麼腳本輸出。

注意:我試圖運行的腳本是一個交互式腳本,所以在調用結束後,控件已經回到python,我如何獲得所有寫在終端中的內容? 有什麼建議嗎?

+0

是否必須寫輸出到'stdout'?我建議只寫入一個文件然後讀取文件。 – Skyler

+0

你需要包含'call'是什麼。 –

+0

@InbarRose:'subprocess.call'據推測。 –

回答

1

我總是使用subprocess.Popen()從一個Python腳本內運行另一個程序變量e.g。例如:

import subprocess 

print "Starting process..." 
process = subprocess.Popen(["echo", "a"], shell=False) 
process.wait() 
print "Done" 

可以處理的輸出重定向到另一個這樣的文件:

import subprocess 

print "Starting process..." 
with open("./out.log", "w") as f: 
    process = subprocess.Popen(["echo", "a"], shell=False, stdout=f) 
    process.wait() 
print "Done" 

重定向標準錯誤,也可以通過「標準錯誤」參數。

當你重定向到寫自己的文件當前的腳本有sys.stdout,你可以做到這一點,以重定向在你的子太:

import subprocess 
import sys 

sys.stdout = open("./out.log", "w") 
print "Starting process..." 
sys.stdout.flush() 
process = subprocess.Popen(["echo", "a"], shell=False, stdout=sys.stdout) 
process.wait() 
print "Done" 
+0

該腳本具有交互功能,用戶必須進行交互,這些腳本是否也會被記錄下來?如果我將stdout傳遞給文件描述符,用戶將無法與腳本交互! –

+0

因此,您希望子流程的輸出在控制檯上都可見並寫入日誌文件?至於交互,當前stdin是隱式傳遞的,用戶將能夠從鍵盤輸入命令。 – ZalewaPL

+0

是的,這就是我想要的!但我希望用戶與腳本本地交互,並且當腳本結束時,變量或stdout可以存儲它在終端中寫入的任何內容。 –

0

正如Martijn Pieters所述,您必須爲您的call()呼叫提供替代stdout

基本上有2種方式: *要麼提供一個已打開的文件(如您已更改sys.stdout,這可能會被罰款) *使用stdout=subprocess.PIPE和閱讀並自己處理stdout。 (不是通過subprocess.call()話,而是通過由subprocess.Popen()返回的對象。)

請注意,更改sys.stdout不會真正改變你的進程的stdout從操作系統的角度出發,而是將你的程序順序輸出都在非 - 實際文件描述符。

1

你可以寫這樣的調用的輸出到使用:

variable = subprocess.Popen(
    ['ls', 'mydir/'], # note that the command is split on whitespace 
    stdout=subprocess.PIPE).communicate()[0] 
+0

我試圖運行的腳本具有交互功能,用戶必須鍵入他們的名字等,這些腳本也會被記錄下來嗎? –

+0

@SunnyRockzzs,所以你想使它可以像''script.py arg1 arg2''那樣調用?如果我理解正確,也許這[堆棧溢出問題](http://stackoverflow.com/questions/4429966/how-to-make-a-python-script-pipeable-in-bash)將帶你進一步 –

+0

我認爲他的意思是他正試圖運行的腳本從stdin讀入。請注意他使用「互動」一詞。所以需要將stdin重定向回運行python腳本的shell。 –

0

這可能是有用的。特別是因爲大多數其他答案不明白你需要將父shell的stdin重定向到子進程的stdin,因爲你調用的程序/腳本是「交互式」的。

Python and subprocess input piping

相關問題