Почему программа, показанная в "7.2.39 IP C :: Open2" в Programming Perl, фактически завершается? - PullRequest
3 голосов
/ 04 августа 2020

Программа, о которой я говорю, является второй программой, показанной в этом разделе здесь . Его небольшая модификация:

#!/usr/bin/perl -w
use IPC::Open2;
use Symbol;

$WTR = gensym();  # get a reference to a typeglob
$RDR = gensym();  # and another one

$pid = open2($RDR, $WTR, 'bc');
print "$pid\n";

while (<STDIN>) {           # read commands from user
    print $WTR $_;          # write a command to bc(1)
    $line = <$RDR>;         # read the output of bc(1)
    print STDOUT "$line";   # send the output to the user
}

Эта программа работает нормально. Скажем, его имя - prop_7_2_39_2.pl, поэтому типичное взаимодействие с ним:

>./prop_7_2_39_2.pl
75955
2+2
4
quit

>

То есть после ввода «quit» дочерний процесс bc перестает функционировать, и после этого мне нужно кормить новая строка, чтобы фактически завершить sh родителя perl. Почему <STDIN> оценивается как ложное? Я понимаю, что perl оценивает определение <STDIN>. Несколько родственная программа

#!/usr/bin/perl -w
while(<STDIN>){}

не заканчивается.

1 Ответ

2 голосов
/ 04 августа 2020

После отправки quit на bc он завершается, что закрывает конец чтения канала. Ваш следующий print $WTR $_ завершится ошибкой и сгенерирует сигнал SIGPIPE, завершающий программу - если вы не установите для него обработчик сигнала.

Альтернативным решением может быть проверка чтения из bc после того, как вы отправил что-то ему удалось:

while (<STDIN>) {              # read commands from user
    print $WTR $_;             # write a command to bc(1)
    my $line = <$RDR>;         # read the output of bc(1)

    if($line) {
        print STDOUT "$line";  # send the output to the user
    } else {
        last;                  # break out of the while loop
    }
}
print "Controlled ending...\n";
...