2016-12-02 14 views
0

オプションでSTDINからの入力を受け付けるプログラムのラッパースクリプトを作成しています。私のスクリプトはファイルの各行を処理する必要がありますが、STDINをラッピングしているプログラムに転送する必要もあります。私は実際にcatが、それだけでSTDINが正しく転送されているかどうかを実証する例としてのラップしようとしていないよstdinから読み込み、Pythonのサブプロセスに転送します

import subprocess 
import sys 

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

subprocess.call(['cat']) 

注:ミニマリスト形式では、これは次のようになります。

上記の例では、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. サブプロセスは一度だけ呼び出すことができます。ですから、一度に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

この解決策には2つの問題があります。 1.すべての回線ではなく、最初の回線だけを転送します。 'readlines'(複数形)を使用してサブプロセスと通信するときにそれらを結合する必要があります。 2.これは私がすでに提示した同じ解決策で、ちょっと動き回っています。ファイル全体をメモリに読み込むという欠陥があります。私はより多くのメモリ効率的なソリューション(存在する場合)を探しています。 –

+0

ここで大声で考えてください。サブプロセスの後のコードがwhileループ内にあって、連続して1行で読み込み、処理してから通信するとどうなりますか?それはあなたが探しているのと同じようなストリーミング的なアプローチではないでしょうか? – bkvaluemeal

+0

追加の制約を参照してください:#1。 –

関連する問題