Автор Тема: Реализация fork на shell-скриптах?  (Прочитано 3262 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн epros

  • Активный пользователь
  • **
  • Topic Author
  • Сообщений: 71
Реализация fork на shell-скриптах?
« : 24 Ноябрь 2013, 23:27:55 »
Мне тут потребовалось запустить демон из скрипта php (модуль Apache). Тупые методы типа:

`command &`не срабатывают: Если command успевает запуститься до завершения скрипта, то скрипт просто не хочет завершаться - вероятно, ждёт завершения дочернего процесса, не глядя на то, что тот запущен в фоне.

К моему сожалению, также выяснилось, что модуль управления потоками (pcntl) из php, скомпилированного как модуль Apache, недоступен. В частности, нет функции pcntl_fork(). Однако в консольной версии php это всё есть. Поэтому я наваял примерно такой скрипт:

Файл 'start_daemon':

#!/usr/bin/php5
<?php
function shutdown($child_pid) {
   
posix_kill($child_pidSIGKILL);
}

$child_pid pcntl_fork(); // Разветвляем процесс

if ($child_pid) { // Это ветка родительского процесса

    
register_shutdown_function('shutdown'$child_pid);
      
// Функция shutdown будет вызвана при завершении родительского процесса
      // чтобы убить дочерний процесс после того, как он запустит демон
    
sleep(1);
      
// Даём дочернему процессу секунду на запуск демона
    
exit;
}
      
// А эта ветка выполняется только в дочернем процессе.

`setsid command &`;
      
// Команда setsid отвязывает демон command от родителя:
      // дочернего процесса php, который его запустил
?>
который можно запустить как из консоли, так и командой из того php, который модуль Apache.

Например так:

`start_daemon`;

А можно это как-то написать не в форме php-скрипта, а обычным bash-скриптом? Что-то я не нашёл никакой команды, аналогичной pcntl_fork().
« Последнее редактирование: 24 Ноябрь 2013, 23:30:00 от epros »
 

yura_n

  • Гость
Re: Реализация fork на shell-скриптах?
« Ответ #1 : 25 Ноябрь 2013, 01:12:15 »
Если я правильно понимаю, вы хотите запустить из Bash процесс таким образом, чтобы он отвязался от текущего окружения. Самое смешное:
#!/bin/bash
start_daemon &
Новый скрипт будет запущен уже в форке. Bash форкует окружение по умолчанию.
 

Оффлайн epros

  • Активный пользователь
  • **
  • Topic Author
  • Сообщений: 71
Re: Реализация fork на shell-скриптах?
« Ответ #2 : 25 Ноябрь 2013, 12:51:12 »
Если я правильно понимаю, вы хотите запустить из Bash процесс таким образом, чтобы он отвязался от текущего окружения. Самое смешное:
#!/bin/bash
start_daemon &
Новый скрипт будет запущен уже в форке. Bash форкует окружение по умолчанию.
Хм, я не понял идеи. start_daemon - это файл с php-скриптом, который я хотел переписать. Если Вы имели в виду:

Файл start_daemon:

#!/bin/bash
command &
(command - это тот демон, которого нужно запустить), то это, конечно, будет работать из командной строки, но при попытке запустить этот файл из php-скрипта, который Apache запускает по запросу от веб-клиента, php-скрипт не завершается. Т.е. клиенту приходится нажимать в браузере кнопку "стоп".
« Последнее редактирование: 25 Ноябрь 2013, 12:55:57 от epros »
 


yura_n

  • Гость
Re: Реализация fork на shell-скриптах?
« Ответ #3 : 25 Ноябрь 2013, 17:46:50 »
но при попытке запустить этот файл из php-скрипта, который Apache запускает по запросу от веб-клиента, php-скрипт не завершается.
Вероятно, это заморочка PHP интерпретатора. Он хочет вывести результат выполнения внешней программы на стандартный вывод и ждет пока она не выполнится. Вам возможно нужно перенаправить стандартный вывод функции PHP, которая запускает внешнюю программу.
« Последнее редактирование: 25 Ноябрь 2013, 18:00:51 от yura_n »
 

Оффлайн epros

  • Активный пользователь
  • **
  • Topic Author
  • Сообщений: 71
Re: Реализация fork на shell-скриптах?
« Ответ #4 : 26 Ноябрь 2013, 14:49:09 »
Он хочет вывести результат выполнения внешней программы на стандартный вывод и ждет пока она не выполнится. Вам возможно нужно перенаправить стандартный вывод функции PHP, которая запускает внешнюю программу.
Непонятно, что перенаправлять. Если я просто запускаю демон строкой:

`start_daemon`;, то php, по идее, никаких выводов от этой команды ждать не должен. Про крайней мере, если start_daemon написан на php (как описано выше), никаких проблем не возникает - скрипт завершается. Но bash-скрипт почему-то ведёт себя иначе. Кстати, отвязка от родительского процесса командой setsid тоже не спасает. Т.е. вот такой вариант файла start_daemon тоже корректно не отрабатывает:

Файл start_daemon:

#!/bin/bash
setsid command &
« Последнее редактирование: 26 Ноябрь 2013, 14:53:49 от epros »
 

yura_n

  • Гость
Re: Реализация fork на shell-скриптах?
« Ответ #5 : 26 Ноябрь 2013, 16:05:42 »
Непонятно, что перенаправлять.
Из php вы можете сделать что-то вроде:
<?php
exec
('/path_to_file/test.sh > /dev/null &');
?>

Или так:
<?php
exec
('/path_to_file/test.sh > /path_to_file/file &');
?>

Тогда PHP интерпретатор не будет ждать завершения программы.
« Последнее редактирование: 26 Ноябрь 2013, 16:08:53 от yura_n »
 


Теги:
 

C++ Интерфейс и реализация

Автор smallNix

Ответов: 2
Просмотров: 1922
Последний ответ 30 Март 2012, 01:03:54
от smallNix