CORE::system
과 qx
연산자에서 추상화하는 System :: Wrapper 모듈을 작성하고 있습니다. 나는 메서드를 사용하여 command1의 출력을 command2의 입력에 연결하려고 시도합니다. 명명 된 파이프를 사용하여 몇 가지 진전을 이루었지만 POSIX::mkfifo
은 플랫폼 간 호환이 아닙니다.크로스 플랫폼 방식으로 두 개의 Perl CORE :: 시스템 명령을 파이프하는 방법은 무엇입니까?
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
에 대한 대안이 여기system
를 호출 하단에있는run
방법) 지금까지이 무엇의 일부 크로스 플랫폼? Win32 명명 된 파이프는 작동하지 않습니다. 일반 파일로 열 수 없으며, 소켓을 사용하지 않는 이유도 마찬가지입니다.2. 위의 방법은 효과가 없습니다. 두 스레드가 올바르게 생성되지만 아무 것도 파이프를 통해 이동하지 않습니다. 파이프 교착 상태 또는 출력 버퍼링과 관련이 있다고 생각합니다. 나를 없애 버리는 이유는 실제 쉘에서 두 명령을 실행할 때 모든 것이 예상대로 작동한다는 것입니다.
포인트 2가 해결됩니다. a -p
fifo 파일 테스트가 올바른 파일을 테스트하지 않았습니다.
프로그램이 의미있는 출력을 STDOUT으로 출력하거나 STDIN에서 읽을 수 있다고 보장 할 수 없기 때문에 일반 파이프 나 IPC :: Run을 사용할 수 없습니다. 어떤 프로그램은 입력 또는 출력 파일을 인수로 설정해야 할 수도 있고 그렇지 않으면 죽어 갈 수도 있습니다. 'fork'와'threads'는'fork '가 실제로는 창문 아래에서 덜 강력하다는 인상하에 있습니다. 그러나 내가 포크를 통해 스레드를 사용하고있는 진짜 이유는 없습니다. –