子プロセスに標準入力と標準出力を中継
下のようなコードを書いてsedでテストをしていたのだけどうまく動かない。
import sys from subprocess import * from time import sleep cmd = sys.argv[1:] bufsize = 1 p = Popen(cmd, shell=True, stdout=PIPE, stdin=PIPE, bufsize=bufsize) while True: sleep(0.1) print 1 data = sys.stdin.readline() print 2, repr(data) p.stdin.write(data) print 3 data = p.stdout.readline() print 4 sys.stdout.write(data)
こうなってしまう。
$ python ~/tmp/watch_stdin.py "sed s/a/b/g" 1 aaa 2 'aaa\n' 3
本当は子プロセスの標準入力にaaa\nが入ると子プロセスが標準出力にbbbを返すはず。
$ sed s/a/b/g aaa bbb
という悩みをfrsyuki君に相談したらRubyで書いてみたけどやはりsedではうまく行かなくて、catならうまく行くという話。
$ python ~/tmp/watch_stdin.py "cat" 1 aaa 2 'aaa\n' 3 4 aaa 1
ほんとだ、うまく動く。「これはもうsedの実装を読むしかありませんね」(上野氏)
とりあえずきれいにしておいたバージョンを載せる。
import sys from subprocess import Popen, PIPE from time import sleep cmd = sys.argv[1:] bufsize = 1 p = Popen(cmd, shell=True, stdout=PIPE, stdin=PIPE, bufsize=bufsize) while True: sleep(0.1) data = sys.stdin.readline() if not data: break p.stdin.write(data) data = p.stdout.readline() sys.stdout.write(data)