Как я могу перенаправить вывод консольного приложения, которое создает собственный дочерний элемент и перенаправляет вывод своего дочернего элемента? - PullRequest
1 голос
/ 26 апреля 2011

Я использую Perl для выполнения psexec и захвата вывода с консоли. Что мне кажется странным, так это то, что когда я выполняю команду с обратными галочками, она каждый раз корректно фиксирует вывод.

Например, этот Perl-скрипт работает , и я использовал его много лет для разных конфигураций:

use strict;
my @out;
@out = `psexec \\\\192.168.1.105 -u admin -p pass netstat -a`;

print @out;

Этот Perl-скрипт завершается ошибкой и, похоже, надежно вызывает зависание psexesvc на удаленной системе:

use IPC::Open2;

my($chld_out, $chld_in, $pid);
$pid = open2($chld_out, $chld_in, 'psexec \\\\192.168.1.105 -u admin -p pass netstat -a');

waitpid( $pid, 0 );
my $child_exit_status = $? >> 8;
my $answer = <$chld_out>;

print "\n\n answer: $answer";

Что для меня так странно, это то, что у обратных спинок, похоже, никогда не было проблем. Все остальное, включая примеры на C ++ от MSDN .

Я подозреваю, что проблема с IPC :: Open2 и примером в C ++ (ссылка выше) связана с тем, что я перенаправляю STDIN и STDOUT из командной оболочки (cmd.exe) и дочернего процесса (psexec) делает то же самое при связи с моей удаленной системой.

Кроме того, где в perldocs я могу найти подробную информацию о том, как работают обратные пометки? Меня больше всего интересуют их "внутренности" на Windows.

Или, где в источнике Perl я могу просмотреть внутреннюю работу обратных галочек (это может откусывать больше, чем я могу пережевывать, но в этот момент стоит попробовать).

UPDATE : Следуя совету Энди, я обнаружил, что это работает:

use IPC::Open2;

my($chld_out, $chld_in, $pid);
$pid = open2($chld_out, $chld_in, 'psexec \\\\192.168.1.105 -u admin -p pass netstat -a');

my @answer = <$chld_out>;
print "\n\n answer: @answer";

waitpid( $pid, 0 );
my $child_exit_status = $? >> 8;

1 Ответ

2 голосов
/ 26 апреля 2011

Я очень мало знаю о том, как это работает в Windows, поэтому, возможно, кто-то может дать более конкретный ответ, но при передаче данных между процессами в Perl вам нужно быть осторожным, чтобы избежать нежелательных блокировок и взаимоблокировок.В perlipc обсуждаются различные сценарии проблем.

В вашем примере немедленный вызов waitpid вызывает проблемы.Одна возможность состоит в том, что дочерний элемент не может выйти, пока что-то не прочитает вывод, поэтому все зависает, так как родитель не собирается читать вывод.Другая возможность состоит в том, что часть потока данных отключается как часть вызова waitpid, и это вызывает проблему с удаленным процессом.

В любом случае было бы лучше прочитать выходные данные издочерний процесс перед вызовом waitpid.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...