Существует ли Perl-модуль, который может запустить процесс и вернуть этому процессу три основных дескриптора ввода-вывода?

В Perl мне часто нужно запустить дочерний процесс, отправить ему некоторый ввод, а затем прочитать его вывод. Для этого существует несколько модулей, но все они, кажется, требуют от вас передачи уже существующих переменных, которые затем модифицируются функцией, чтобы они содержали файловые дескрипторы. Вот пример из синопсиса IPC::Open3:

my ($wtr, $rdr, $err);
use Symbol 'gensym'; $err = gensym;
$pid = open3($wtr, $rdr, $err,
                'some cmd and args', 'optarg', ...);

Этот шаблон немного раздражает, когда мне приходится делать это снова и снова, особенно потому, что он включает в себя кучу позиционных параметров, которые мне нужно либо помнить, либо искать. Есть ли какой-нибудь модуль, предоставляющий функцию (назовем ее myopen3), которая работает следующим образом?

my ($wtr, $rdr, $err) = myopen3('some cmd and args', 'optarg', ...);

Или он может вернуть хэш или хэш-ссылку соответствующих дескрипторов:

my $process = myopen3('some cmd and args', 'optarg', ...);
$process->{STDIN}->print("Some input");
my $output = $process->{STDOUT}->readline;

Преимущества такой функции в том, что myopen3 вызывается точно так же, как и встроенная system (хотя, надеюсь, без каких-либо причуд), а в случае возврата хэша или хешрефа, позиционные параметры и возврат значения избегаются. (Кроме того, если позже автор модуля решит также вернуть pid и другую информацию о процессе, это можно сделать, сохранив обратную совместимость.)

На самом деле я реализовал это сам (с простым интерфейсом OO), но я бы не стал полагаться на свой собственный пользовательский модуль, если существует модуль CPAN, делающий то же самое.

Самое близкое, что я нашел до сих пор, это IPC::RunSession::Simple, который возвращает объект с методами reader и writer. Однако метод reader объединяет STDOUT и STDERR дочернего процесса, а хотелось бы возможность их разделения.


person Ryan C. Thompson    schedule 21.06.2010    source источник
comment
Кроме того, есть ли у кого-нибудь предложения, как мне назвать модуль, реализующий описанный выше ОО-интерфейс?   -  person Ryan C. Thompson    schedule 25.06.2010


Ответы (1)


Просто напишите свой:

sub myopen3
{
    my ($err, $in, $out);
    my $pid = open3($in, $out, $err, @_);
    return ($pid, $in, $out, $err);
}
person JSBձոգչ    schedule 21.06.2010
comment
Не забудьте инициализировать $err (см. трюк ... = gensym в OP) перед вызовом open3. - person mob; 21.06.2010
comment
Я написал для него свой собственный модуль, но если на CPAN уже существует модуль, делающий то же самое, это облегчает мою жизнь, когда я копирую свои скрипты на другой компьютер, потому что мне не нужно также копировать свои пользовательские модуль и установите его. Но да, мое текущее решение состоит в том, чтобы сделать это самостоятельно. - person Ryan C. Thompson; 21.06.2010