Я построил простой скрипт обработки текста на работе, который будет использоваться другой программой. Когда я закончил, кто-то вспомнил, что сценарий не должен блокировать STDIN/STDOUT для того, чтобы инструмент использовал его для правильной работы и соответствующим образом изменил сценарий. Сценарий открывает * nix cat
в подпроцессе через IPC::Open2
и печатает на нем STDIN, считывает его и затем обрабатывает и печатает его в STDOUT. Я понятия не имею, как это делает скрипт не блокирующим, но он, по-видимому, работал.Windows/Linux дочерний процесс STDIN отличия
Я хотел, чтобы он работал и на Windows, поэтому я изменил cat
на type CON
, что является простой командой Windows для печати STDIN. Пример сценария ниже:
use strict;
use warnings;
use IO::Handle;
use IPC::Open2;
my $command = ($^O eq 'MSWin32') ? 'type CON' : 'cat';
my ($com_reader, $com_writer) = (IO::Handle->new, IO::Handle->new);
open2($com_reader, $com_writer, $command);
# input
while (<STDIN>) {
print "first line: $_";
print $com_writer "$_";
my $line = <$com_reader>;
# ...process $line...
print "next line: $line";
}
Однако результаты совершенно разные. В Windows потоки STDIN для основного скрипта и в дочернем скрипте кажутся разными, в то время как в Linux они одинаковы. В Windows (I тип 1 и 2 на отдельных строках ввода):
>perl test.pl
>1
first line: 1
>2
next line: 2
>1
>2
first line: 2
next line: 1
>1
>2
first line: 2
next line: 1
>1
>2
first line: 2
next line: 1
В Linux (тот же вход):
>perl test.pl
>1
first line: 1
next line: 1
>2
first line: 2
next line: 2
>1
first line: 1
next line: 1
>2
first line: 2
next line: 2
Почему выход отличается, и как я могу сделать поведение Windows, соответствовать поведению Linux? Кроме того, почему этот «открытый кот в подпроцессе и трубе ввода через него» вообще работает?
@Harry Johnston, Двухсторонняя интерактивная связь с дочерним процессом. – ikegami
@harry Johnston, На практике это будет более сложная программа. – ikegami
@Nate: причина, по которой сценарий, как написано, ведет себя странно, заключается в том, что сценарий и дочерний процесс конкурируют за один и тот же источник ввода. –