Prepend Perl программа с фильтром - PullRequest
1 голос
/ 03 мая 2019

Я хочу написать:

... | my_filter | myperlprogram

Но я не знаю, как запустить my_filter, пока я не запустил myperlprogram.

Можно ли как-нибудь в цикле myperlprogramSTDIN через my_filter до прочтения?

Я думаю что-то вроде:

pipe($a,$b);
if(not fork()) {
   close STDOUT; 
   open STDOUT, $b;
   exec "my_filter --with the correct --options";
} else {
   close STDIN
   open STDIN, $a
}
# continue reading STDIN now looped through `my_filter`

Ответы [ 2 ]

5 голосов
/ 03 мая 2019

Из описания не совсем понятно, почему простой

open STDIN, '-|', 'your_filter', '--option1', ...

не подойдет.

1 голос
/ 03 мая 2019

Я вижу проблему в следующем: чтобы отфильтровать STDIN для сценария, используя внешнюю программу, которая запускается изнутри сценария, когда сценарий выполняется (т. Е. Не с конвейером). С IPC :: Run

use warnings;
use strict;
use feature 'say';

use IPC::Run qw(start pump finish);

my $filtered_in;
FILTER_IN: {        
    my @cmd = qw(a_filter.pl);  # add filter's options/arguments
    my $h = start \@cmd, \my $in, \$filtered_in;
    while (<>) { 
        $in = $_; 
        pump $h while length $in;

        # Wait for filter's output -- IF WANT to process lines as received
        pump $h until $filtered_in =~ /\n\z/;
        chomp $filtered_in;                    # process/use filter's output
        $filtered_in .= '|';                   # as it's coming (if needed)
    }    
    finish $h or die "Cleanup returned: $?";
};    
say $filtered_in // 'no input';

Это позволяет обрабатывать строки вывода фильтра по мере их выдачи. Если это не нужно, но мы хотим накапливать выходные данные фильтра на более поздний срок, тогда вам не нужен код под # Wait for...


Простейший тест с a_filter.pl, например

use warnings;
use strict;
STDOUT->autoflush(1);

my $cnt = 0;    
while (<>) { print "line ", ++$cnt, ": ", $_ }

, а затем запустить

echo "a\nfew\nlines" | script.pl

с выводом

line 1: a|line 2: few|line 3: lines|

из нашей обработки игрушек в script.pl выше.

Это также отфильтрует ввод через файл,

script.pl < input.txt
...