2016-12-06 3 views
1

私のPythonプログラムでは、で接続された2つのsubprocessesと、に接続された1つのstdinが接続されています。私の問題は、データフローが終了すると、ctrl+cを押すまでサブプロセスがハングすることです。サブプロセスが私のパイプを開いているように見えます。パイプを流れるデータがいつ手作業で閉じることができるかを知ることができたら、パイプを通るデータがいつ終了するかを確認する方法

def write(tag_name): 
    p_r, p_w = os.pipe() 
    pv = subprocess.Popen('pv', stdin=None, stdout=p_w) 
    dd = subprocess.Popen('dd bs=64k of=/dev/nst0'.split(), stdin=p_r, stdout=None) 
    dd.wait() 

答えて

1

だけos.pipe()を使用しないでください、あなたはこのように、他のプロセスstdinに直接サブプロセスstdoutを渡すことができます。os.pipe()とは対照的に、最初のコマンドが終了するが、パイプが(壊れている

def write(tag_name): 
    pv = subprocess.Popen('pv', stdin=None, stdout=subprocess.PIPE) 
    dd = subprocess.Popen('dd bs=64k of=/dev/nst0'.split(), stdin=pv.stdout, stdout=None) 
    dd.wait() 

手動で閉じる必要があるため)、2番目のコマンドも終了し、スクリプトは続行/終了できます。

私は単純なパイプコマンドをテストしましたが、os.pipe()で説明したようにブロックされますが、最初のプロセスが変更されて終了しました。

+0

'' pv'行にOSRrror:[Errno 9] Bad file descriptor'を出しています。 –

+0

Pythonマニュアル 'subprocess.STDOUT'を見ると、' Popen.stderr'の引数としてしか使用できません。あなたが言ったように、 'stdout = subprocess.PIPE'を渡すことができます。 –

+0

申し訳ありませんが、タイプミス! 'subprocess.PIPE'に固定 –

0

ここにノンブロッキングソリューションが必要です。 https://github.com/vesellov/bitdust.devel/blob/master/system/nonblocking.py

をそして、あなたはこのようにそれを呼び出すことができます(コードをテストしていませんでした): 私の解決策を見てみましょう

import nonblocking, time 
p = nonblocking.Popen('pv'.split(), shell=True,) 
p.make_nonblocking() 
while 1: 
    if p.state() == nonblocking.PIPE_CLOSED: 
     # pipe closed, stop 
     return break 
    if p.state() == nonblocking.PIPE_READY2READ: 
     newchunk = p.recv(1024) 
     if newchunk == '': 
      # EOF reached, stop 
      break 
     # do something with the data here 
     # you can send it to second stream 
    try: 
     time.sleep(0.01) 
    except KeyboardInterrup: 
     break 

をだからあなたは)dd.wait(コールそれがブロックされたとき、つまり、なぜCtrl-Cが機能しないのかこれを手動で処理する必要があります....非ブロックストリーミングは、Pythonでは些細な話ではありません。チェックアウトTwisted project、あなたはたくさんのクールなものを見つけることができます:-)

+0

興味深い解決策は、100KB/sに制限された帯域幅があるという欠点のみです。私の場合、 'dd.wait()'は 'Ctrl-C'を停止していません。実際には' Ctrl-C'を押すとパイプがガベージコレクトされ、サブプロセスはきれいに終了します。 –

+0

ええ、必要に応じて 'time.sleep()'間隔を調整することができます。 –

関連する問題