запуск «less» из конвейера perl

Я пытаюсь настроить произвольные конвейеры из 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";
}

Однако, когда я делаю второй аргумент «меньше», мой терминал мигает, и я не вижу вывода в пейджере. Кроме короткой вспышки, нет никаких признаков меньшего пробега.

Теперь я совсем не понимаю, что следующее ведет себя как "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 (). Первый аргумент должен быть "читателем", а второй - "писателем". Как STDIN является «писателем»?

Я очень сбит с толку всем этим и думаю, что в базовом API Unix может быть что-то фундаментальное, что я упустил или забыл.

6
задан projix 24 July 2012 в 23:20
поделиться