pro*_*jix 6 perl fork pipe exec dup
我试图从Perl设置任意管道,就像shell一样.
这有所期望的效果,就像"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";
}
Run Code Online (Sandbox Code Playgroud)
但是,当我将第二个参数设置为"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";
Run Code Online (Sandbox Code Playgroud)
但我完全不了解对pipe()的调用.第一个论点应该是"读者",第二个论点是"作家".STDIN如何成为"作家"?
我对这一切感到非常困惑,并认为可能存在一些基本的Unix API,我缺少或者我已经忘记了.
这是一个有趣的时间问题:
perl.perl叉子和高管less.perl高管echo.echo 退出,shell认为工作已完成,并再次将自己设置为终端前台进程组.less试图获得终端.它不在终端前台进程组中. less失败.最简单的解决方案:更改fork为!fork(或等效地,交换您的if和else块).这样,管道的最后阶段定义了工作的生命周期.(如果仔细观察,shell在运行管道时也会以相同的顺序分叉和执行进程.)