2012-03-11 17 views
10

私は次の行に、サブプロセスを使用したい:Pythonのサブプロセス:パイプを3回使う方法?

convert ../loxie-orig.png bmp:- | mkbitmap -f 2 -s 2 -t 0.48 | potrace -t 5 --progress -s -o ../DSC00232.svg 

私は他の記事the subprocess documentationに感謝を発見したが、一例では、我々は二回しかパイプを使用しています。

だから、私は三つのコマンドの2のために試してみて、それが

p1 = subprocess.Popen(['convert', fileIn, 'bmp:-'], stdout=subprocess.PIPE) 
# p2 = subprocess.Popen(['mkbitmap', '-f', '2', '-s', '2', '-t', '0.48'], stdout=subprocess.PIPE) 
p3 = subprocess.Popen(['potrace', '-t' , '5', '-s' , '-o', fileOut], stdin=p1.stdout,stdout=subprocess.PIPE) 
p1.stdout.close() # Allow p1 to receive a SIGPIPE if p3 exits. 
output = p3.communicate()[0] 

は、あなたが3番目のコマンドのために私を助けることができる作品?

ありがとうございました。

+1

あなたは、同じプロセスで3番目のコマンドのために再びそれを試してみましたか? –

+0

あなたが試したことがなぜうまくいかなかったのですか?シェル内のすべてのパイプは、あるプロセスのstdoutを別のプロセスのstdoutに接続します。 – Dunes

+0

私はp2をどこに閉じなければならないのかわかりませんし、出力をコード化する方法もありません。 – Zorkzyd

答えて

19

ただ、同じ例に続く第3のコマンドを追加します。オプションshell=True

p1 = subprocess.Popen(['convert', fileIn, 'bmp:-'], stdout=subprocess.PIPE) 
p2 = subprocess.Popen(['mkbitmap', '-f', '2', '-s', '2', '-t', '0.48'], 
    stdin=p1.stdout, stdout=subprocess.PIPE) 
p1.stdout.close() 
p3 = subprocess.Popen(['potrace', '-t' , '5', '-s' , '-o', fileOut],   
    stdin=p2.stdout,stdout=subprocess.PIPE) 
p2.stdout.close() 

output = p3.communicate()[0] 
+0

私はそう信じていません、彼らはすべてリンクされているので、私はただ一つの '通信'呼び出しが必要と思われると思います。それは動作しましたか? –

+0

はい、今動作します。ありがとう:) – Zorkzyd

+2

'p1.stdout.close()'と 'p2.stdout.close()'が 'output = p3.communicate()[0]'の後に来るかどうかは重要ですか? – sandyp

5

使用subprocess.Popen()を、あなたは1つの文字列としてそれをあなたの全体のコマンドを渡すことができます。その後

+0

これはたいていの方法です(もっと簡単です)が、 'fileIn'や' fileOut'にスペースがあった場合など、ファイル名の引用問題に遭遇することがあります。たいていは 'pipes.quote'を使って処理することができますが、' shell = False'は技術的に安全です。 – torek

1
def runPipe(cmds): 
try: 
    p1 = subprocess.Popen(cmds[0].split(' '), stdin = None, stdout = subprocess.PIPE, stderr = subprocess.PIPE) 
    prev = p1 
    for cmd in cmds[1:]: 
     p = subprocess.Popen(cmd.split(' '), stdin = prev.stdout, stdout = subprocess.PIPE, stderr = subprocess.PIPE) 
     prev = p 
    stdout, stderr = p.communicate() 
    p.wait() 
    returncode = p.returncode 
except Exception, e: 
    stderr = str(e) 
    returncode = -1 
if returncode == 0: 
    return (True, stdout.strip().split('\n')) 
else: 
    return (False, stderr) 

それが好きで実行します。

runPipe(['ls -1','head -n 2', 'head -n 1']) 
関連する問題