シェルとほぼ同じ方法で、Perl から任意のパイプラインをセットアップしようとしています。
これには望ましい効果があります。「echo foo | sed s/oo/ar/」のようになります。
#!/usr/bin/perl
use strict;
use IO::Handle;
$| = 1;
my ($first_prog, $second_prog) = ([qw(echo foo)], [qw(sed s/oo/ar/)]);
#$second_prog = ["less"];
pipe(my $second_prog_input, my $first_prog_output)
or die "problem setting up pipe: $!\n";
if (fork) {
STDOUT->fdopen(fileno($first_prog_output), 'w') or die;
exec(@$first_prog) or die;
}
else {
STDIN->fdopen(fileno($second_prog_input), 'r') or die;
exec(@$second_prog) or
die "couldn't exec: $!: command was @$first_prog\n";
}
ただし、2 番目の引数を「less」にすると、端末が点滅し、ページャーに出力が表示されません。短い閃光を除けば、走る気配がまったくない。
今、私がまったく得られないのは、次のものが「echo foo | less」のように動作することです。
pipe(my $first_prog_output, STDIN) or die "problem setting up pipe: $!\n";
my ($first_prog, $second_prog) = ([qw(echo foo)], ["less"]);
open($first_prog_output, "-|", @$first_prog) or
die "$!: command was @$first_prog\n";
exec(@$second_prog) or
die "couldn't exec: $!: command was @$first_prog\n";
しかし、pipe() の呼び出しが何をしているのかまったくわかりません。最初の引数は「リーダー」で、2 番目の引数は「ライター」です。STDINはどのように「ライター」ですか?
私はこれらすべてに非常に困惑しており、根底にある Unix API について何か基本的なことが欠けているか忘れているのではないかと考えています。