今まであんまパイプ付きopen使わずに、system()とかbackticsばかりだったので、ちゃんと理解しておくことにした。
open()関数は "-|" や "|-" といったファイル引数を非常におも しろいことを行うために受け付けます: これはあなたがオープンしたフ ァイルハンドのための子プロセスをfork()するのです。その子プロセス は親プロセスと同じプログラムを実行します。
if ($pid) { # parent print KID_TO_WRITE @some_data; close(KID_TO_WRITE) || warn "kid exited $?"; } else { # child ($EUID, $EGID) = ($UID, $GID); # suid プログラムのみ open (FILE, "> /safe/file") || die "can't open /safe/file: $!"; while (<STDIN>) { print FILE; # 子プロセスの STDIN は親プロセスの KID } exit; # これを忘れてはいけません }
確かに、openした後は親子な処理になってます、waitって勝手にするんだろうか?おそらくするんだろうなと思うが、waitしてるかってどうやって確かめればよいんだろう?
また、ここまで理解すれば、次のサンプルもなかなかすっきりしてると思えるようになる。
コマンド -' を用いてパイプを open する場合、 すなわち
|-' または`-|' の場合、 暗黙の内に fork がなされ、 open の返り値は親プロセスでは子プロセスの pid、 子プロセスでは 0 になる。
||がif ($pid) {} else {}と同じだということはわかる。
open(FOO, "|-") || exec 'tr', '[a-z]', '[A-Z]';
ということはこの式も実はforkしているのか。
open(FOO, "|tr '[a-z]' '[A-Z]'");
あと、Higher-order Perlのp.152の例だとtacの出力を"|-"でつないでるんだよな。おかしいなぁと思ったらやっぱ間違ってた。ちなみにいま6章読んでる。