Perl Script, Fork/Exec, System утверждает, что мой процесс умер, хотя на самом деле умер только мой дочерний процесс

У меня есть Perl-скрипт, который выполняет fork/exec для запуска другого инструмента в фоновом режиме и отслеживания некоторых изменений файловой системы во время работы этого другого инструмента. Кажется, это работает так, как ожидалось.

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

Моя проблема в том, что как только мой дочерний процесс умирает, Bash возвращается к своей подсказке, утверждая, что мой процесс завершен... что не соответствует действительности. Очевидно, что он все еще работает в фоновом режиме и ожидает модификации файловой системы. Если я продолжаю печатать какой-либо текст в основном цикле скрипта, этот текст все равно печатается, даже если bash уже вернулся к приглашению.

Я не могу понять, что заставляет bash считать, что мой процесс завершился. Я пытался заблокировать сигнал SIGCHLD в своем скрипте, я пытался закрыть и/или перенаправить STDOUT/STDERR/STDIN (которые дублируются на форке, но кто знает) - безуспешно. Я даже попробовал знаменитую «двойную вилку», чтобы сделать конечный дочерний элемент независимым от моего скриптового процесса, и результат тот же. Что бы я ни делал, как только мой ребенок (или внук) умирает, Баш считает, что мой процесс остановился. Запуск моего сценария в фоновом режиме (используя «&» в конце) заставляет Bash даже сказать мне, что процесс XYZ завершен (и он называет здесь мой процесс, а не дочерний процесс, хотя мой процесс счастливо жив и печатает на терминал через STDOUT в тот же момент).

Если бы это была проблема только с Bash, мне было бы все равно, но другое стороннее программное обеспечение, которое должно запускать мой скрипт, действует так же. Как только мой ребенок умирает, они утверждают, что мой сценарий на самом деле умер, что просто не соответствует действительности.


person Mecki    schedule 17.11.2009    source источник
comment
Я думаю, что вместо этого прозаического описания для вас было бы полезнее вместо этого сократить свой код до минимально возможного размера, который иллюстрирует вашу проблему, и опубликовать это. Если в процессе этого ваша проблема исчезнет, ​​вы получили полезную информацию для отладки.   -  person Adam Bellaire    schedule 17.11.2009
comment
Согласен с Адамом. Покажи мне код! (Извинения перед Джерри Магуайром.)   -  person Chris Jester-Young    schedule 17.11.2009
comment
Извините, что не опубликовал код, после попыток найти причину этой проблемы в течение примерно 30 минут у меня оставалось ровно 10 минут до того, как мне нужно было уйти (иначе я бы пропустил важную встречу) - описание выше было лучшим, что я может появиться в течение 10 минут (разборка кода до минимального тестового примера заняла еще немного времени). У меня снова есть доступ к коду ровно через 11 часов; тогда я посмотрю, что я могу сделать с образцом кода.   -  person Mecki    schedule 18.11.2009


Ответы (1)


Просто проверка работоспособности, ваша основная программа идет по правильной вилке? Он должен следовать ненулевому пути:

my $pid = fork;
if ($pid == 0) {
    print "Child\n";
} else {
    print "Main\n";
}

Из форка man:

После успешного завершения fork() возвращает значение 0 дочернему процессу и возвращает идентификатор дочернего процесса родительскому процессу.

person Andomar    schedule 17.11.2009
comment
Ммм... хорошее замечание... Я еще раз проверю это ровно через 11 часов (именно тогда у меня снова будет доступ к моему коду). Это действительно было бы глупой ошибкой, но каждый время от времени совершает глупые ошибки, и если бы он выполнял exec не в том форке, это действительно соответствовало бы нежелательному поведению, описанному выше. - person Mecki; 18.11.2009
comment
Вы правы — вывод отладочного вывода прямо перед тем, как exec показывает, что exec работает в родительском, а не в дочернем — ДУХ! Глупая ошибка!!! - person Mecki; 18.11.2009