Я пишу модуль System :: Wrapper, чтобы абстрагироваться от CORE::system
и оператора qx
. У меня есть метод serial
, который пытается подключить вывод команды command1 к входу команды2. Я добился определенного прогресса, используя именованные каналы, но POSIX::mkfifo
не является кроссплатформенным.
Вот часть того, что у меня есть (метод run
внизу в основном вызывает system
):
package main;
my $obj1 = System::Wrapper->new(
interpreter => 'perl',
arguments => [-pe => q{''}],
input => ['input.txt'],
description => 'Concatenate input.txt to STDOUT',
);
my $obj2 = System::Wrapper->new(
interpreter => 'perl',
arguments => [-pe => q{'$_ = reverse $_}'}],
description => 'Reverse lines of input input',
output => { '>' => 'output' },
);
$obj1->serial( $obj2 );
package System::Wrapper;
#...
sub serial {
my ($self, @commands) = @_;
eval {
require POSIX; POSIX->import();
require threads;
};
my $tmp_dir = File::Spec->tmpdir();
my $last = $self;
my @threads;
push @commands, $self;
for my $command (@commands) {
croak sprintf
"%s::serial: type of args to serial must be '%s', not '%s'",
ref $self, ref $self, ref $command || $command
unless ref $command eq ref $self;
my $named_pipe = File::Spec->catfile( $tmp_dir, int \$command );
POSIX::mkfifo( $named_pipe, 0777 )
or croak sprintf
"%s::serial: couldn't create named pipe %s: %s",
ref $self, $named_pipe, $!;
$last->output( { '>' => $named_pipe } );
$command->input( $named_pipe );
push @threads, threads->new( sub{ $last->run } );
$last = $command;
}
$_->join for @threads;
}
#...
Мои конкретные вопросы:
Есть ли альтернатива POSIX::mkfifo
, которая является кроссплатформенной? Именованные каналы Win32 не работают, так как вы не можете открыть их как обычные файлы, так же как и сокеты, по тем же причинам.
2. Выше не совсем работает; две нити появляются правильно, но по трубе ничего не течет. Я полагаю, что это может быть связано с блокировкой канала или буферизацией вывода. Меня отталкивает то, что когда я запускаю эти две команды в реальной оболочке, все работает как положено.
пункт 2 решен; -p
Проверка файла fifo не проверяла правильный файл.