Хотите получить сообщение об ошибке die из команды, выполненной через open в Perl
Я пытаюсь раскошелиться на cmd как ниже
my $h = IO::Handle->new;
$self->{-handle} = $h;
die "IO::Handle->new failed." unless defined $h;
$self->{-pid} = open $h, $self->{-command} . ' 2>&1 |';
$self->fileevent($h, 'readable' => [\&_read_cmd_op, $self]);
sub _read_cmd_op{
my $h = $self->{-handle};
if ( sysread $h, $_, 4096 ) {
my $t = $self->Subwidget('text');
$t->insert('end', $_);
$t->yview('end');
} else {
$self->{-finish} = 1;
}
}
Теперь проблема в том, что $self{-command} вызывает другой Perl-скрипт, который, если умрет, я хочу знать.
Обратите внимание, что $self{-pid} все еще существует, даже если cmd умирает.
Приведенный выше код находится в приложении Perl/TK, где $self->{-command} o/p захвачено в текстовом виджете.
Почему-то я не получаю сообщение die даже в тестовом виджете. Я вижу это на stdout.
2 вопроса
Как я могу получить cmd op/error в текстовом виджете?
Как я могу узнать, что команда, запущенная через IO::Handle, умерла?
1 ответ
$self->{-pid}
это просто pid разветвленного процесса, а не какой-то магический объект, который исчезает при выходе из команды.
Я не могу воспроизвести проблему, не получая die()
сообщение. Если приведенный выше фрагмент вызывается с 'perl -e "die 123"'
затем в текстовом виджете появляется "123" (по крайней мере, в системе Unix).
Для получения кода выхода вы можете использовать что-то вроде следующего.
} else {
$mw->fileevent($h, 'readable', '');
my $pid = waitpid($self->{-pid},0);
warn "pid $pid finished";
warn "retcode is " . ($? >> 8);
$self->{-finish} = 1;
}
fileevent
Вызов с пустым обратным вызовом останавливает дальнейший выбор по этому дескриптору файла. При вызове waitpid вы ожидаете завершения дочернего процесса. Как только это произойдет, код выхода доступен в $?
переменная, как после нормального system()
вызов. Так что для ненулевого кода выхода вы знаете, что команда умерла или вышла с ложным значением.