2012-01-22 30 views
4

在Linux上,我使用supbprocess.Popen來運行應用程序。該應用程序的命令行需要輸入文件的路徑。我瞭解到我可以將路徑/ dev/stdin傳遞到命令行,然後使用Python的subproc.stdin.write()將輸入發送到子進程。你能打開stdin作爲MS Windows上的Python文件嗎?

import subprocess 
kw['shell'] = False 
kw['executable'] = '/path/to/myapp' 
kw['stdin'] = subprocess.PIPE 
kw['stdout'] = subprocess.PIPE 
kw['stderr'] = subprocess.PIPE 
subproc = subprocess.Popen(['','-i','/dev/stdin'],**kw) 
inbuff = [u'my lines',u'of text',u'to process',u'go here'] 
outbuff = [] 
conditionbuff = [] 

def processdata(inbuff,outbuff,conditionbuff): 
    for i,line in enumerate(inbuff): 
     subproc.stdin.write('%s\n'%(line.encode('utf-8').strip())) 
     line = subproc.stdout.readline().strip().decode('utf-8') 
     if 'condition' in line: 
      conditionbuff.append(line) 
     else: 
      outbuff.append(line) 

processdata(inbuff,outbuff,conditionbuff) 

還有這個應用程序的MS Windows版本。在MS Windows上有相當於使用/ dev/stdin還是Linux(Posix)特定解決方案?

+0

相關:[視窗相當於「/dev/stdin"?](http://stackoverflow.com/questions/7395157/windows-equivalent-to-dev-stdin) –

回答

1

如果myapp對待-作爲一個特殊的文件名,它表示標準輸入,則:

from subprocess import PIPE, Popen 

p = Popen(['/path/to/myapp', '-i', '-'], stdin=PIPE, stdout=PIPE) 
stdout, _ = p.communicate('\n'.join(inbuff).encode('utf-8')) 
outbuff = stdout.decode('utf-8').splitlines() 

如果不能通過-那麼你可以使用一個臨時文件:

import os 
import tempfile 

with tempfile.NamedTemporaryFile(delete=False) as f: 
    f.write('\n'.join(inbuff).encode('utf-8')) 

p = Popen(['/path/to/myapp', '-i', f.name], stdout=PIPE) 
outbuff, conditionbuff = [], [] 
for line in iter(p.stdout.readline, ''): 
    line = line.strip().decode('utf-8') 
    if 'condition' in line: 
     conditionbuff.append(line) 
    else: 
     outbuff.append(line) 
p.stdout.close() 
p.wait() 
os.remove(f.name) #XXX add try/finally for proper cleanup 

要壓制stderr你可以p ass open(os.devnull, 'wb') as stderr to Popen

+0

我試過' - ',這個程序不支持它。此外,在這種情況下,溝通()不會工作,因爲我需要在此代碼中未顯示的逐行控制。 – tahoar

+0

@tahoar:您能否更新您的問題並詳細說明您的情況下「逐行控制」的含義? – jfs

+0

@sebastion:查看更新。溝通()的另一個問題是它可能需要一些時間(10-15分鐘)才能加載進程。這種方法不僅可以讓我逐行處理數據,還可以多次調用循環,而無需重新加載應用程序。我懷疑STDIN問題是特定於操作系統的,我僅限於Posix平臺而不更改所調用的應用程序。 – tahoar

2

,則不應使用'/dev/stdin'sys.stdin

+2

你如何將'sys.stdin'作爲'-i'選項來傳遞? – jfs

1

在黑暗中總拍攝,但con:是控制檯設備的名稱(您知道,來自DOS的好ol'copy con newfile.txt)。您可能能夠將con:作爲參數傳遞給不接受' - '的程序。

0

請使用

進口SYS

sys.stdout.write函數( 「ABC \ N123 \ n」)

在SYS線.stdin.readlines():

... print線

例如

相關問題