pipeを他プロセスから読み書きする

長らくpipeは自プロセスもしくは 親子プロセスでしか読み書きできないものと思っていたが、 最近、他のプロセスからも読み書き可能なことを発見した。つまり/proc/pid/fdを使えばよい。

自分としてはかなりの驚きであった。

例えば、

#!/usr/bin/env perl
use strict;
use warnings;

pipe my $read, my $write or die $!;

while (my $line = <$read>) {
    warn "-> GOT: $line";
}

というのを用意したとき下記のように通信できる。

$ perl pipe.pl &
[1] 13801

$ ls -l /proc/13801/fd
total 0
lrwx------ 1 skaji skaji 64 Nov  6 15:30 0 -> /dev/pts/6
lrwx------ 1 skaji skaji 64 Nov  6 15:30 1 -> /dev/pts/6
lrwx------ 1 skaji skaji 64 Nov  6 15:30 2 -> /dev/pts/6
lr-x------ 1 skaji skaji 64 Nov  6 15:30 3 -> pipe:[4096813]
l-wx------ 1 skaji skaji 64 Nov  6 15:30 4 -> pipe:[4096813]

# filedescriptor4が書き込み用pipeなのでそこに書き込む。
$ perl -E 'open my $fh, ">", "/proc/13801/fd/4" or die $!; say {$fh} "hello from $$"'
-> GOT: hello from 13843

なお、同じやり方で例えば tmpfile(3)によってopen、すぐunlinkされたファイルも他プロセスから読み書き可能だ。