Запустить дочерний процесс

no_santa

Снегур
Запустить дочерний процесс

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

Никак не соображу, как форкнуть на PHP что-то типа exec('script.sh','/dev/null')? Или по-грамотному это можно сделать как-то по другому?

Спасибо за добрые ответы!

-~{}~ 22.08.09 19:29:

вывод действительно не нужен, логи складируются sh, надо только запустить его.
 

no_santa

Снегур
Спасибо!

-~{}~ 22.08.09 19:59:

извините за глупый вопрос, а просто exec('script.sh > /dev/null'); нельзя?
и второй вопрос - в мануале PHP написано, что если exec не имеет второго параметра, дочерний процесс прервется при завершении работы PHP.
 

Alexandre

PHPПенсионер
exec('script.sh > /dev/null 2>&1 &');
крайне ошибочное мнение, РНР скрипт будет ожидать, так как функция exec вызывает окружение, в котором будет выполняться skript.sh в бэдграунде и после окончания работы в бэдграунде всех процессов, она вернет код возврата. Одними словами для РНР скрипта что 'script.sh > /dev/null 2>&1 &' что 'script.sh > /dev/null 2>&1' без & все равно РНР скрипт начнет выполнять следующую команду после exec по окончании скрипта script.sh.

можете поэксперементировать со sleep(10).

для запуска скрипта в бэдграунде я использую простую C программу:
PHP:
int  main(){
		switch (fork()) {
		case -1:
			return -1;
		
		case 0:
			break;
		
		default:
                        system "/usr/bin/bash script.sh";
			exit(0);
		}		
	}
запускаю ее через system("/full/path/myproga");
 

point

Новичок
При запуске в background-e код возварата всегда 0 и управление интерпретатору (sh, tcsh, etc) отдается сразу с этим кодом. Например,
Код:
sleep 10 &
-~{}~ 22.08.09 21:56:

Только что провел полевые испытания.
Есть shell скрипт 1.sh

Код:
#/bin/sh

sleep 10
touch test.file
Запуск этого скрипта в такой форме:

Код:
php -r 'system("./1.sh > /dev/null 2>&1 &");echo "qwe";'
выдаст на stdout строку qwe сразу же. А файл test.file, который создается в скрипте создастся лишь через 10 сек, как указано в sleep-e

Так что ваш "стартер" на Си -- явное усложнение.
 

Alexandre

PHPПенсионер
Код:
<? // sleep.php
sleep(10);
echo "**************\n";
?>

<?  // test.php
system ( "/usr/local/bin/php /tmp/sleep.php  &" );
echo '======================';
?>
запускаем test.php что с & что без - результат вывода через 10 сек....
может у меня комп глючит, просьба кого-нибудь третьего проверить у себя тоже....
 

point

Новичок
- system ( "/usr/local/bin/php /tmp/sleep.php &" );
+ system ( "/usr/local/bin/php /tmp/sleep.php > /dev/null &" );
 

no_santa

Снегур
в мане написано, что это делается exec('script.sh',$output) - если указать $output, тогда script.sh продолжит свою работу после PHP, т.е. PHP не будет ждать ответа от script.sh

Вопрос - что можно указать для вывода, если логи и ответ действительно не нужны (они уже складируются script.sh)
 

point

Новичок
>в мане написано

Пруф в студию!

> если указать $output, тогда script.sh продолжит свою работу после PHP, т.е. PHP не будет ждать ответа от script.sh

Это как ? Интерперетатор вызвал system и перешел к следующей команде, но при этом наполняя $output строками вывода скрипта script.sh ??

> Вопрос - что можно указать для вывода, если логи и ответ действительно не нужны

Как в примере выше -- укажи /dev/null
 

no_santa

Снегур
Как в примере выше - не работает, первый скрипт прерывает дочерний через 30 сек. Попробуй.


Прув http://ru2.php.net/function.exec
 

point

Новичок
Не поверишь, не просто пробовал -- тестировал перед тем как опубликовать здесь.

Пруф -- конкретное место из мана, где написано
что это делается exec('script.sh',$output) - если указать $output, тогда script.sh продолжит свою работу после PHP, т.е. PHP не будет ждать ответа от script.sh
 

no_santa

Снегур
попробуй еще раз - дочерний скрипт прерывается через 30 сек после запуска
 

Alexandre

PHPПенсионер
юзайте pcntl, он не ждет )
однако он не для реал-тайм...или в ман носом ткнуть
+ system ( "/usr/local/bin/php /tmp/sleep.php > /dev/null &" );
пробовал - но результат тот же... забыл добавить 2>&1, но не думаю что это решит проблему ;)
отпишусь позже.
 

point

Новичок
> забыл добавить 2>&1, но не думаю что это решит проблему

По идеи, именно это и решит проблему
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
5.3 fcgi-fpm

system ( "/usr/local/bin/php sleep.php" );
ждем дочку
[root@vm www]# netstat -px |grep php
unix 3 [ ] STREAM CONNECTED 81294 22046/php-cgi /var/run/php-fcgi.sock
unix 3 [ ] STREAM CONNECTED 81133 22045/php-cgi
... 1 воркер занят
[root@vm www]# ps axu |grep php
root 22045 0.0 1.7 22232 4508 ? Ss 02:26 0:00 /usr/local/bin/php-cgi --fpm
php 22046 0.0 2.0 22528 5180 ? S 02:26 0:00 /usr/local/bin/php-cgi --fpm
php 22089 2.0 2.7 20528 7088 ? S 02:34 0:00 /usr/local/bin/php sleep.php
sleep() кушает 2% проца :)

system ( "/usr/local/bin/php sleep.php > /dev/null &" );
возврат моментальный, дочка осталась
[root@vm www]# netstat -px |grep php
unix 2 [ ] STREAM CONNECTED 81482 22101/php /var/run/php-fcgi.sock
unix 3 [ ] STREAM CONNECTED 81133 22045/php-cgi
unix 3 [ ] STREAM CONNECTED 81132 22045/php-cgi
unix 3 [ ] STREAM CONNECTED 81129 22045/php-cgi
unix 3 [ ] STREAM CONNECTED 81128 22045/php-cgi
все воркеры свободны, а за дочкой остается открытый сокет, оказывается
[root@vm www]# ps axu |grep php
root 22045 0.0 1.7 22232 4508 ? Ss 02:26 0:00 /usr/local/bin/php-cgi --fpm
php 22046 0.0 2.0 22528 5180 ? S 02:26 0:00 /usr/local/bin/php-cgi --fpm
php 22107 2.0 2.7 20536 7088 ? S 02:35 0:00 /usr/local/bin/php sleep.php
без неожиданностей

однако ...

system ( "/usr/local/bin/php sleep.php &" );
ждем дочку

[root@vm www]# ps axu |grep php
root 22045 0.0 1.7 22232 4508 ? Ss 02:26 0:00 /usr/local/bin/php-cgi --fpm
php 22046 0.0 2.0 22528 5180 ? S 02:26 0:00 /usr/local/bin/php-cgi --fpm
php 22110 0.0 0.0 0 0 ? Z 02:36 0:00 [sh] <defunct>
php 22111 0.4 2.7 20532 7088 ? S 02:36 0:00 /usr/local/bin/php sleep.php

что значит этот <defunct> ?
 

dimagolov

Новичок
grigori, раз зашла речь о fcgi-fpm. у тебя есть опыт что лучше, unix socket или tcp для связи nginx <-> php ?

что значит этот <defunct>
To google!!!
Processes marked <defunct> are dead processes (so-called "zombies") that
remain because their parent has not destroyed them properly. These processes
will be destroyed by init(8) if the parent process exits.
то есть, как я понимаю, порядок действий такой. php-cgi создает дочерний шелл-процесс, с которого пайпит вывод чтобы его вернуть скрипту. шелл получает "/usr/local/bin/php sleep.php &" и прускает CLI в фоне, но вывод тоже пайпит на себя (фоновые процессы вполне в живые териминалы, с которых были запущены, пишут). То есть процесс sh не делает ничего, кроме состыковки потоков между CLI & cgi. Все что он мог, он исполнил, а вывод ему умереть не дает. Если делаем > /dev/null, то sh потоков никаких не получает от дочки и соответственно дохнет естественной смертью.

п.с. про открытые сокеты не понял, так как никакой связи дочернего CLI процесса с сокетами не усмотрел

-~{}~ 26.08.09 21:10:

п.п.с. а когда "/usr/local/bin/php sleep.php &", то вывод реально попадает через зомбю в родительский скрипт? понятно, что дочка должна завершиться для этого....
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
http://www.lexa.ru/nginx-ru/msg18633.html
на линуксе на продакшене - только tcp
nginx не так как надо работает с unix sockets под нагрузками
на фре можно юникс-сокет, он быстрей

про открытые сокеты - netstat показывает
unix 2 [ ] STREAM CONNECTED 81482 22101/php /var/run/php-fcgi.sock
(22101 - пид дочки)
ежу понятно, что сам процесс к этому отношения не имеет
но почему так и что это значит - я не знаю

-~{}~ 27.08.09 03:35:

про <defunct> - спасибо, подзабыл man ps :)
 
Сверху