2015-09-21 43 views
-1

我想按順序運行多個python程序,我想捕獲stdout或每個進程的輸出使用臨時文件或者(如果有更好的方法可以做到這一點)。將由文件或從進程1生成的多個文件的輸出將用作下一個進程的輸入。怎麼做?從子進程stdout捕獲多個文件到一個臨時文件用於下一個子進程

所以我的代碼是這樣的:

# multiple files 
for file in files: 
    P1 = Popen('python Prog1.py' + ' ' + file, stdout=PIPE , stderr=STDOUT,shell=True) 
    # Now I want to capture the output to files so can be used for the next process 
    # It didn't work 
    l_out_files.append(P1.stdout) 
    # Prog2 require if the input file is more than one to have them separated by space 
P2 = Popen('python Prog2.py' + ' ' + ' '.join(l_out_files), stdout=PIPE , stderr=STDOUT,shell=True) 

非常感謝球員,

最佳

+0

什麼是你真正想傳球,都是p1和p2在循環? –

+0

@PadraicCunningham我修正了這個問題,p1進入循環,但是位於p2。 – BioInformatician

+0

所以Prog2.py需要一串文件名?另外,爲什麼不從python做所有這些,你的程序實際上在做什麼? –

回答

2

至於你自己的代碼都附加P1.stdout,只是附加的方法引用你的清單很明顯是不行的,那就是P1.communicate()[0]來提取輸出。

我想這可能都無需子做,但你可以創建輸出列表與check_output,真的不知道爲什麼要重定向錯誤輸出到標準輸出兩種:

from subprocess import check_output,STDOUT 

data = [check_output(['python', 'Prog1.py', file], stderr=STDOUT) for file in files] 

out = check_output(['python', 'Prog2.py',' '.join(data)], stderr=STDOUT) 

check_output會引發錯誤的任何非零退出狀態,它可能應該作爲傳遞任何錯誤輸出到您的python程序會更有可能打破它。

捕捉任何錯誤,你可以使用try /除了趕CalledProcessError

from subprocess import check_output,STDOUT, CalledProcessError 

data = [] 
for file in files: 
    try: 
     data.append(check_output(['python', 'Prog1.py'], stderr=STDOUT)) 
    except CalledProcessError as e: 
     print(e.message) 
+0

這沒有奏效。 Prog1顯示一些消息,供用戶通過分析狀態等等通知他們,這些消息僅用check_output捕獲,而不是在Prog1中寫入文件的實際輸出。 – BioInformatician

+0

如何捕捉寫入文件的輸出?如果你認爲你需要添加你的代碼實際上在做什麼,以及你期望發生什麼 –

+0

使用''Prog2.py'] +文件名'而不是''Prog2.py',''.join(data)]' 「Prog1.py」在將結果存儲到標準輸出的地方寫入文件名 – jfs

0

它看起來像你想模仿bash process substitution

#!/usr/bin/env python 
from subprocess import check_call 

check_call('prog2 <(prog1 file1) <(prog1 file2) <(prog1 file3) ...', 
      shell=True, executable='/bin/bash') 

其中prog2運行python Prog2.pyprog1運行python Prog1.py。 它假定prog1將其結果寫入標準輸出並且prog2在命令行上接受其輸入文件名。 Bash進程替換允許將輸出從prog1傳遞到prog2,而不會將數據寫入磁盤,也不會將其全部存儲在內存中(以防它可能很大)。

雖然你可以在沒有shell的純Python中執行它(the link shows named pipe-based and fdescfd (/dev/fd/#) -based solutions,但如果需要可以使用其他方法);它會更容易,如果prog2將接受標準輸入的輸入:

#!/usr/bin/env python 
from subprocess import check_call 

check_call('{ prog1 file1; prog1 file2; prog1 file3; ...; } | prog2', 
      shell=True) 

你可以做到這一點在純Python沒有外殼:

#!/usr/bin/env python3 
from subprocess import Popen, PIPE, check_call 

with Popen('prog2', stdin=PIPE) as prog2: 
    for filename in files: 
     check_call(['prog1', filename], stdout=prog2.stdin) 
相關問題