Почему мой Perl-скрипт возвращает нулевой код возврата, когда я явно вызываю выход с ненулевым параметром?

У меня есть скрипт Perl, который вызывает другой скрипт. Сценарий Perl должен распространять код возврата сценария, но, похоже, возвращает ноль своему вызывающему объекту (приложению Java), несмотря на явный вызов exit $scriptReturnCode.

Код и вывод следующим образом (я понимаю, что <=> может/должно быть !=, но это то, что у меня есть):

print "INFO: Calling ${scriptDirectory}/${script} ${args}"
$scriptReturnCode = system("${scriptDirectory}/${script} ${args}");

if ( $scriptReturnCode <=> 0 ) {
        print "ERROR: The script returned $scriptReturnCode\n";
        exit $scriptReturnCode;
} else {
        print "INFO: The script returned $scriptReturnCode.\n";
        exit 0;
}

Вывод, который у меня есть из моей Java:

20/04/2010 14:40:01 - INFO: Calling /path/to/script/script.ksh arg1 arg2 
20/04/2010 14:40:01 - Could not find installer files <= this is from the script.ksh    
20/04/2010 14:40:01 - ERROR: The script returned 256
20/04/2010 14:40:01 - Command Finished. Exit Code: 0 <= this is the Java app.

person Tom Duckering    schedule 21.04.2010    source источник


Ответы (2)


Вам нужно сдвинуть код возврата из вызова system() на 8 бит.

Например. $exit_value = $? >> 8; # В вашем скрипте $? это $scriptReturnCode

Из http://perldoc.perl.org/perlfaq8.html:

system() запускает команду и возвращает информацию о статусе выхода (в виде 16-битного значения: младшие 7 бит — это сигнал, из-за которого процесс умер, если таковой имеется, а старшие 8 бит — фактическое значение выхода).

Более расширенная проверка кода на дампы ядра также может выглядеть так:

system();
if ($? == -1) {
    print "failed to execute: $!\n";
} elsif ($? & 127) {
    printf "child died - signal %d, %s coredump\n",
           ($? & 127), ($? & 128) ? 'with' : 'without';
} else {
    printf "child exited with value %d\n", $? >> 8;
}

ОБНОВЛЕНИЕ: согласно отличному напоминанию ysth, коды выхода усекаются до 8 (младших) битов, поэтому возврат 256 вместо предполагаемой 1 заканчивается как 0. Точно так же возврат 257 заканчивается как 1.

person DVK    schedule 21.04.2010
comment
Предположим, вы имеете в виду shift как в $scriptReturnCode = $scriptReturnCode >> 8; - person Tom Duckering; 21.04.2010
comment
В идеале явно добавить, что коды выхода усекаются до 8 (младших) битов, поэтому возврат 256 вместо предполагаемой 1 заканчивается как 0. Точно так же возврат 257 заканчивается как 1 и т. д. - person ysth; 21.04.2010

Если захват $? и сдвиг его значения слишком сложны для запоминания, вы можете упростить этот код, используя IPC::System::Simple, который дополняет system() и обратные кавычки дополнительной проверкой и диагностикой ошибок, например:

use IPC::System::Simple qw(run EXIT_ANY);

my $command = "${scriptDirectory}/${script} ${args}";
print "INFO: Calling $command\n";

# runs command through a shell first; does not die on any exit value
run(EXIT_ANY, $command);
my $scriptReturnCode = $IPC::System::Simple::EXITVAL;
person Ether    schedule 21.04.2010