$? = 13
означает, что ваш дочерний процесс был прерван сигналом SIGPIPE
.Ваша внешняя программа (bp_genbank2gff3.pl
) попыталась записать какой-либо вывод в канал для вашей perl
программы.Но программа perl
закрыла свой конец канала, поэтому ваша ОС отправила SIGPIPE
во внешнюю программу.
Используя sleep
в течение 3 секунд, вы позволяете своей программе работать в течение 3 секунд, прежде чемОС убивает его, так что это позволит вашей программе что-то сделать.Обратите внимание, что каналы имеют ограниченную емкость, поэтому, если ваш родительский сценарий perl
не читает из канала и если внешняя программа много пишет в стандартный вывод, операции записи внешней программы в конечном итоге блокируются, и вы, возможно, на самом деле неполучите 3 секунды усилий от вашей внешней программы.
Обходной путь - прочитать выходные данные внешней программы, даже если вы просто собираетесь их выбросить.
open( my $command_out, "-|", $command );
my @ignore_me = <$command_out>;
close $command_out;
Обновление: Если вы действительно не заботитесь о выводе команды, вы можете избежать проблем SIGPIPE
, перенаправив вывод в /dev/null
:
open my $command_out, "-|", "$command > /dev/null";
close $command_out; # succeeds, no SIGPIPE
Конечно, если вы собираетесь пойти на такие неприятности, чтобы проигнорировать вывод, вы также можете просто использовать system
.
Дополнительная информация : в качестве OPговорит, что закрытие переданного по конвейеру файлового дескриптора заставляет родителя ждать, пока ребенок завершит работу (используя waitpid
или что-то подобное).Но до начинает ждать, закрывает конец трубы.В этом случае этот конец является концом чтения канала, в который дочерний процесс записывает свой стандартный вывод.В следующий раз, когда дочерний объект пытается что-то записать в стандартный вывод, ОС обнаруживает, что конец чтения этого канала закрыт, и отправляет SIGPIPE
дочернему процессу, убивая его и быстро допуская оператор close
в родительском процессе..