Вилка в Perl, но получите статус выхода от системного вызова в детском процессе
Вопрос
Что я делаю:
- Сделайте призыв Ajax к сценарию CGI.
- Скрипт CGI Forks, но родитель возвращается сразу же ответом MSG.
- Ребенок делает системный вызов, но нуждается в коде выхода и любых сообщениях об ошибках.
Псевдокод:
$SIG{CHLD} = ‘IGNORE’; # or waitpid($pid,0) in the parent process
$pid = fork();
if($pid == 0)
{
close STDOUT; # So that the parent sends the response to the client right away.
@errorMsgs = qx(tar up big directories over 50G…); # This can go on for a few minutes.
if($? ==0) { Send a ‘success’ email } # Is always false ($? == -1)
else { Send a ‘failure’ email }
}
elsif($pid){ sendResponse; waitpid($pid,0) if $SIG{CHLD} != 'IGNORE'; exit;}
Моя проблема:
Проблемы с получением правильного кода возврата ($?) И любых сообщений об ошибках от qx (), так как он установлен на -1 из -за ($ sig {chld} = 'игнорировать'). Если я удалю $ sig {chld}, веб -страница клиента не получает ответный сигнал от родителя до тех пор, пока ребенок не будет получен.
Решение
Вы получаете -1, потому что вы настраиваете $SIG{CHLD}
к IGNORE
. Анкет Делая это, вы убиваете qx
Возможность захватить код выхода tar
... он умрет, не уведомив родителя (ваш ребенок -процесс).
Это достаточно просто, чтобы проверить:
perl -e '$SIG{CHLD} = "IGNORE"; system("ps"); print "Finished with $?\n";
Это дает -1.
perl -e 'system("ps"); print "Finished with $?\n";
Это дает 0.
Если вам действительно нужен $SIG{CHLD} = 'IGNORE'
, тогда просто $SIG{CHLD} = 'DEFAULT'
перед вашим qx
вызов.
Кроме того, убедитесь, что вы используете полный путь к tar
(например /bin/tar
) на случай, если у вас нет /bin
На вашем пути, и он не выполняет. Тем не менее, я предполагаю, что это нормально, так как вы ничего не сказали о том, что ваш файл DAR не создается.
Другие советы
Ну, если вы сбросите $SIG{CHLD}
к undef
В детском разделе (т.е. $pid == 0
), это не повлияет на родительский процесс, верно?