Perl вызывает оболочку - прерывание ^ C останавливает оболочку, а не Perl - PullRequest
2 голосов
/ 10 марта 2011

Я хочу использовать скрипт Perl для пакетирования повторяющейся операции, которая вызывается с помощью system (). Когда что-то идет не так, и я хочу прервать этот сценарий, оболочка захватывает ^ C, останавливая любую работу, и сценарий Perl весело переходит к следующему.

Есть ли способ, которым я могу вызвать задание, чтобы прерывание остановило сценарий Perl?

Ответы [ 2 ]

9 голосов
/ 10 марта 2011

Вы можете проверить $?, чтобы увидеть, умерла ли команда, выполненная системой, от сигнала 2 (INT):

Вот полный пример разбора $?:

my $rc=system("sleep 20"); 
my $q=$?; 
if ($q == -1) { 
    print "failed to execute: $!\n"
} elsif ($? & 127) { 
    printf "child died with signal %d, %s coredump\n",  
           ($q & 127), ($q & 128) ? 'with' : 'without';
} else { 
    printf "child exited with value %d\n", $q >> 8;
}
# Output when Ctrl-C is hit: 
# child died with signal 2, without coredump

Поэтому точный чек, который вы хотите:

my $rc=system("sleep 20"); 
my $q=$?; 
if ($q != -1 &&  (($q & 127) == 2) && (!($? & 128))) { 
        # Drop the "$? & 128" if you want to include failures that generated coredump
    print "Child process was interrupted by Ctrl-C\n";
}

Ссылки: система perldoc для обработки $? и вызова system(); perldoc perlvar для более подробной информации о $?

5 голосов
/ 10 марта 2011

Вы не проверяете возвращаемое значение system. Добавить в родительскую программу:

use autodie qw(:all);

и программа будет прервана, как и ожидалось:

"…" died to signal "INT" (2) at … line …

Вы можете поймать это исключение с помощью Try :: Tiny , чтобы выполнить очистку самостоятельно или использовать другое сообщение.

...