Когда возникает ошибка, скорее всего не будет в STDOUT
, и если он находится в STDERR
вы не поймать что. Вам нужно перейти к коду выхода приложения следующим образом. (Учитывая обновление на вопрос, который я только видим сейчас: Смотрите в конце для того, как получить STDERR.)
После capture
метода вы хотите исследовать $?
на наличие ошибок (см Net-OpenSSH). Распаковка, что, чтобы получить код завершения, возвращаемый что на самом деле управляет $ssh
, а затем посмотреть в документации этого приложения, чтобы увидеть, что означает, что код
$exit_code = $?;
if ($exit_code) {
$app_exit = $exit_code >> 8;
warn "Error, bit-shift \$? --> $app_exit";
}
Код для исследования является $app_exit
.
Пример. Я использую zip
в проекте и иногда улавливаю ошибку 3072
(то есть $?
). Когда это распакованно, как указано выше, я получаю 12
, то есть фактический выход zip
. Я просматриваю его документы, и он красиво перечисляет его коды выхода и 12
означает Ничего не обновлено. Это дизайнерское решение для zip
, для выхода с 12
, если у него не было файлов для обновления в архиве. Затем этот выход упаковывается в двухбайтовое число (в верхнем байте) и , что возвращается и, следовательно, я получаю в $?
.
режимы отказов в общем, от system в документации Perl
if ($? == -1) { warn "Failed to execute -- " }
elsif ($? & 127) {
$msg = sprintf("\tChild died with signal %d, %s coredump -- ",
($? & 127), ($? & 128) ? 'with' : 'without');
warn $msg;
} else {
$msg = sprintf("\tChild exited with value %d -- ", $? >> 8);
warn $msg;
}
Фактический код выхода $? >> 8
подается независимо от RAN и поэтому его интерпретация до этого приложения. Вам нужно просмотреть его документы и, надеюсь, его коды выхода будут задокументированы.
Отметьте, что $ssh->error
кажется предназначен для этой задачи. Из документов модуля
my $output = $ssh->capture({ timeout => 10 }, "echo hello; sleep 20; echo bye");
$ssh->error and warn "operation didn't complete successfully: ". $ssh->error;
Печатная ошибка требует дальнейшего изучения.Документы не говорят, что это такое, но я бы ожидал, что распакованный код, описанный выше (, это обновление). Здесь $ssh
выполняет только команду и не знает, что пошло не так. Он просто возвращает код выхода команды, чтобы посмотреть.
Или вы можете изменить команду, чтобы получить STDERR
на STDOUT
, см. Ниже.
capture
метод является эквивалентом обратных кавычек в Perl (qx
). Существует много на SO о том, как получить STDERR
от backticks, а собственный FAQ для Perl имеет то, что красиво написано in perlfaq8
. Усложнение состоит в том, что это не qx
, а метод модуля и, что более важно, он работает на другой машине. Однако метод «перенаправления вывода» должен работать без изменений. Команда (выполняется $ssh
) может быть записана так, чтобы ее STDERR
перенаправлялся на ее STDOUT
.
$cmd_all_output = 'your_whole_command 2>&1';
$ssh->capture($cmd_all_output);
Теперь вы получите сообщение об ошибке, которое вы видите на терминале («нет такого файла или каталога»), напечатанной на STDOUT
, таким образом, он будет ветер в вашем $stdout
. Обратите внимание, что необходимо использовать синтаксис оболочки sh
, как указано выше. Для этого есть немного больше, поэтому, пожалуйста, просмотрите его (но это должно работать так, как оно есть). В большинстве случаев это то же сообщение, что и в описании кода выхода.
Проверка, что у вас есть в вашем коде хорошо, первая линия обороны: один должен всегда проверка $?
при выполнении внешних команд, и для этого команду для запуска не нужно трогать.
отредактировал вопрос. :) – geek
вы можете использовать '$ ssh -> error'. в чем проблема? –