2016-12-02 73 views
0

我正在爲可選接受來自STDIN的輸入的程序編寫包裝腳本。我的腳本需要處理文件的每一行,但它也需要將STDIN轉發到它正在打包的程序。在簡約的形式,這看起來是這樣的:從stdin讀取並將其轉發到Python中的子進程

import subprocess 
import sys 

for line in sys.stdin: 
    # Do something with each line 
    pass 

subprocess.call(['cat']) 

請注意,我沒有真正試圖總結cat,而只是作爲一個例子來說明是否STDIN被正確轉發。

用上面的例子,如果我註釋掉for循環,它可以正常工作。但是如果我用for循環運行它,沒有任何東西會被轉發,因爲我已經閱讀了STDIN的結尾。我不能seek(0)到文件的開始,因爲你不能在流上尋找。

一個可能的解決方案是將整個文件讀入內存:

import subprocess 
import sys 

lines = sys.stdin.readlines() 
for line in lines: 
    # Do something with each line 
    pass 

p = subprocess.Popen(['cat'], stdin=subprocess.PIPE) 
p.communicate(''.join(lines)) 

其作品,但不是很高效利用內存。任何人都可以想出更好的解決方案嗎也許一種分割或複製流的方法?

附加約束:

  1. 子進程只能被調用一次。所以我不能一次讀一行,處理它,並將它轉發給子進程。
  2. 解決方案必須在Python 2.6
+0

如果我理解正確的這個,你想從'stdin'基本數據轉發給子進程的'stdin'? – bkvaluemeal

+0

是的,但如果我只想把'stdin'轉發給子進程,'subprocess.call(['cat'])'將是我所需要的。我想轉發'stdin'並且能夠讀取和處理它。 –

回答

0

不工作這對你的工作?

#!/usr/bin/env python2 
import subprocess 
import sys 

p = subprocess.Popen(['cat'], stdin = subprocess.PIPE) 

line = sys.stdin.readline() 

#################### 
# Insert work here # 
#################### 

line = line.upper() 

#################### 

p.communicate(line) 

例子:

$ echo "hello world" | ./wrapper.py 
HELLO WORLD 
+0

該解決方案有兩個問題: 1.它只轉發標準輸入的第一行,而不是每行。您需要使用'readlines'(複數),並在將它們傳遞給子進程時加入它們。 2.這是我已經提出的同樣的解決方案,混亂了一下。它具有將整個文件讀入內存的缺陷。我正在尋找更高效的內存解決方案(如果存在的話)。 –

+0

在這裏大聲思考。如果子進程之後的代碼在while循環內連續讀取一行,處理它然後進行通信呢?這不是一種類似於您所尋找的類似流式的方法嗎? – bkvaluemeal

+0

請參閱其他約束條件:#1。 –