2007/01/12
既存のプロセスの stdout をフィルタするには?
以下は完全にネタ。普通は実行前に tee するなりします。
「既存のプロセスの stdout をフィルタしたいんですけど?」と開発部長に尋ねたところ、 gdb 使えばいいじゃんって話になったのでその方法を紹介。僕の環境では本体プログラムが sevg しちゃいましたが、理論的には動くはず。本気でやるなら ptrace 使う。ちなみに開発部長は gdb が大好きだと思います。
まずはフィルタしたいプログラムを立ちあげておく。
% perl -e 'while (1) { sleep 1; print "Hello\n", "World\n"; }'
んで pid を調べて gdb で attach 。
% pidof perl 1234 % gdb /usr/bin/perl 1234
フィルタプログラムを作るまでの手順は以下のとおり。
- pipe(fds) する
- close(1) して dup(fds[0]) する
- fork する
- child process のほうに attach
- close(0) して dup(fds[1]) する
- フィルタプログラムを exec する
- たぶんこれでいけるはず!
gdb:
> set $fds={0,0} > call pipe($fds) > call close(1) > call dup($fds[0]) > set follow-fork-mode child > call fork() > call close(0) > call dup($fds[1]) > call execlp("grep", "-v", "Hello")
なんか set follow-form-mode child して fork すると問答無用で本体が segv します。原因不明。そもそもやり方が相当変態。
もうちょっと根本的にやるなら tty をとっかえたりすればいいらしいのですが、この辺いまいちよくわかってないのです。
でまあ、個人的に変態度の高いのは、 screen で logging しつつそのファイルを tail -f からフィルタプログラムに渡すという方法。まあそこまでしてやろうとは思いませんが。
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/matsuyama/filter-existed-process-stdout/tbping