os.pipe を使って subprocess.Popen する時の注意
ファイルディスクリプタは subprocess.Popen (というか fork)時にコピーされます。
なので、親プロセスと子プロセスの両方で、必要のないディスクリプタを閉じる必要があります。
しかしこれ、子プロセスが既存のコマンド(例えば tail)だったらファイルディスクリプタ閉じるのって無理じゃね?とか思ったのですが、fork して exec するまでの間に呼んでくれる、preexec_fn 関数というのを指定できるようなので、それを使います。
import os from subprocess import Popen r,w = os.pipe() p = Popen(["tail", "-f", "hoge"], stdout=w, preexec_fn = lambda: os.close(r)) # 子プロセスの読み込み側を閉じる os.close(w) # 親プロセスの書き込み側を閉じる # あとは好きなだけ読む rfd = os.fdopen(r) for line in rfd: print line[:-1]
ただ、このコードだと、例外が起こった時にファイルディスクリプタ漏れる気がするので、もうちょいマジメにコード書かないといけないですね。