2015-05-30 4 views
1

У меня есть скрипт Perl, который должен выполнять некоторую работу на фоне. Это хорошо описано - я fork, kill (return 0) родительский и выполняю работу с дочерним элементом. Когда я запускаю его непосредственно из оболочки, он работает как ожидалось (т. Е. Возвращается в оболочку сразу после убийства родителя и продолжается на фоне). Но если я запустил его из другой среды, например. от PHP через выполнениеPerl на фоне при вызове из другого env

php -r "passthru('my-perl-script.pl')" 

он возвращается в оболочку после того, как ребенок сделан. Любые идеи, почему это происходит?

Спасибо!

EDIT: Вот код Perl я использую:

#!/usr/bin/env perl 
use strict; 
use warnings; 

local $| = 1; 

# fork the process - returns child pid to the parent process and 0 
# to the child process 
print ' [FORKING] '; 
my $pid = fork(); 
error('Failed to fork: [email protected]') and exit 1 if [email protected]; 

# exit parent 
print ' [KILLING PARENT] '; 
exit 0 if $pid; 

# continue as child process 
print " [CONTINUING AS CHILD] \n"; 

# wait 3 secs (for testing) and exit 
sleep 3; 
print " [DONE]\n"; 
exit 1; 

Вывод при выполнении непосредственно:

$ ./background-test.pl 
[FORKING] [KILLING PARENT] [KILLING PARENT] [CONTINUING AS CHILD] 
$ [DONE] 

Вывод при выполнении с помощью PHP:

$ php -r "system('./background-test.pl');" 
$ [FORKING] [KILLING PARENT] [KILLING PARENT] [CONTINUING AS CHILD] 
    # ... 3 seconds wait ... 
    [DONE] 
$ 

Мой вопрос почему сценарий Perl не отключается при вызове из других сред (здесь PHP есть j пример).

Спасибо!

+1

Просьба представить миниатюрную демонстрационную версию проблемы. – ikegami

+0

Я добавил образец кода Perl, который использовался для демонстрации проблемы. Спасибо – baa2w

ответ

1

Если я правильно понимаю, вы говорите, что PHP ждет окончания внука, даже если ребенок вышел.

system не возвращается с php собирает STDOUT ребенка, тот же STDOUT, который был унаследован внуком. В системе Linux, это можно увидеть, добавив следующую строку в скрипт на Perl:

system("ls -l /proc/$$/fd"); 

Из оболочки:

lrwx------ 1 ikegami ikegami 64 Jun 1 14:07 1 -> /dev/pts/0 

От PHP:

l-wx------ 1 ikegami ikegami 64 Jun 1 14:08 1 -> pipe:[10052926] 

Обычно, когда вы deamonize процесс, вы снова открываете его STDIN, STDOUT и STDERR, перенаправляя их на /dev/null или в файл журнала.

open(STDIN, '<', '/dev/null') or die $!; 
open(STDOUT, '>', '/dev/null') or die $!; 
open(STDERR, '>>', '/var/log/application.log') or die $!; 

Обычно, когда вы deamonize процесс, вы также называют POSIX::setsid().

+0

Спасибо за ответ. Точно так же система работает и возвращается в оболочку после завершения дочернего процесса. – baa2w

+0

Обновлен мой ответ. – ikegami

+0

Хм кажется, что перенаправление STDOUT на/dev/null делает трюк. Благодаря! – baa2w