Разветвите в perl, но получите статус выхода из системного вызова в дочернем процессе - PullRequest
3 голосов
/ 28 апреля 2011

Что я делаю:

  1. Выполните ajax-вызов сценария cgi.
  2. Cgi-сценарий разветвляется, но родитель сразу же возвращает сообщение msg.
  3. Ребенок выполняет системный вызов, но ему нужен код выхода и любые сообщения об ошибках.

Псевдокод:

$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} = 'IGNORE').Если я удалю оператор $ SIG {CHLD}, веб-страница клиента не получит ответное сообщение от родителя до тех пор, пока не будет получен ребенок.

Ответы [ 2 ]

6 голосов
/ 28 апреля 2011

Вы получаете -1, потому что вы устанавливаете $SIG{CHLD} в IGNORE.Делая это, вы убиваете способность qx захватывать код выхода tar ... он умрет без уведомления родителя (вашего дочернего процесса).

Это достаточно просто для тестированияout:

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, и этоне в состоянии выполнить.Тем не менее, я предполагаю, что это нормально, так как вы ничего не сказали о том, что ваш tar-файл не создается.

2 голосов
/ 28 апреля 2011

Что ж, если вы сбросите $SIG{CHLD} на undef в дочернем разделе (т.е. после $pid == 0), это не повлияет на родительский процесс, верно?

...