Как сделать скрипт демоном

Обновлено: 04.07.2024

Демон или (от анг. daemon) это программа в системах класса UNIX, запускается самой ОС и работает в фоновом режиме без взаимодействия с пользователем. Демоны обычно запускаются во время загрузки системы.
Для создания демона необходимо выполнить установку ПО и настроить его автозагрузку при старте системы. Обычно если
устанавливаемая программа предназначена для использования в качестве демона, то соответствующие инструкции выполняются в автоматическом режиме и не требуют вмешательства.
Имеется несколько вариантов автоматического запуска демонов в Unix подобных системах. Например, для сервера Ubuntu без графического интерфейса используется классический вариант помещения системных файлов в папку /etc/init.d.

Соответственно в папках:

/etc/rc0.d, размещаются файлы, которые выполняются автоматически при запуске

/etc/rc1.d, размещаются файлы, которые выполняются автоматически при остановке системы

Такие файлы запуска принято называть с символа S (от анг. Start), а останова — с символа K (от анг. Kill); после этого символа указывается число, определяющее порядковый номер запуска и остановки). Для запуска службы в эти папки просто помещают ссылки
на командный файл запуска в папке /etc/init.d.
Такие ссылки создать можно и вручную, но правильней использовать команду update-rc.d. Эта утилита автоматически создает ссылки при установке демона или удаляет их в противном случае. Для создания демона достаточно выполнить:

update-rc.d файл_запуска defaults

С ключом remove эта команда удаляет соответствующие ссылки. Следующий пример показывает отключение демона apache:

Демон — это программа не имеющая стандартного ввода и вывода, и при этом работающая в фоновом режиме.

Исходный код простейшего демона:

В первую очередь вызывается функция fork , которая создает копию процесса. В родительском-процессе функция вернет PID порожденного дочернего процесса, а в дочернем процессе fork вернет 0.

Вызов setsid создает новую сессию. Создание новой сессии обеспечит нас следующими преимуществами: процесс становится лидером новой сессии, процесс становится лидером новой группы процессов и у процесса нет управляющего терминала.

Ну и вызов close(stdin), close(stdout), close(stderr) закрывают файловые дескрипторы стандартного ввода и вывода.

Реализация функции mainloop зависит от от назначения демона, поэтому код этой функции здесь не приведен.

Запись опубликована в рубрике Великий и могучий Си с метками linux, posix. Добавьте в закладки постоянную ссылку.

8 комментариев: Как создать демона в linux

Скажите пож. как мне чтобы каждые 5 минут на сервере выполнялась проверка, существует ли процесс ts3server_linux и если его не существует, то выполнялась бы команда
/home/teamspeak3-server_linux-x86/ts3server_startscript.sh start
от имени пользователя tssrv

Можно написать скрипт, который проверяет запущен ли процесс (например так: ps -C ts3server_linux || /home/teamspeak3-server_linux-x86/ts3server_startscript.sh start ). И прописать запуск этого скрипта в crontab.

А еще посоветую посмотреть в сторону специально заточенных для этих целей утилит, daemontools или runit.

Если нужна более подробная информация — пишите, может смогу помочь.

Затупил… Закрыли мы для дочернего процесса, а вывод для родителя

Чёрная магия :) Работа программиста и шамана имеет много общего — оба бормочут непонятные слова, совершают непонятные действия и не могут объяснить, как оно работает…

setsid();
chdir("/");
fclose(stdin);
//оставим вывод в консоль наш демон будет периодически выводить дату и время
// fclose(stdout);
fclose(stderr);
demon();
>

Посмотреть номер версии Python
Когда Python установлен в Linux (установка по умолчанию), вы можете просмотреть номер версии Python, введя простую команду:

Видно, что версия Python, поставляемая с системой, - 2.7.5.

Здесь я выбрал версию 3.7.2.

распаковать
После завершения загрузки разархивируйте:

Конфигурация установки
Войдите в распакованный каталог, установите и настройте:

Это означает, что не установлен подходящий компилятор. В это время вам необходимо установить / обновить gcc и другие зависимые пакеты.

После завершения повторите:

Скомпилировать и установить
После завершения настройки вы можете скомпилировать:

Долгое ожидание . После его завершения устанавливаем:

проверка
После успешной установки вы можете проверить версию Python:

Один - это старая версия 2.x, а другой - новая версия 3.x.

Примечание. В каталоге / usr / local / bin / есть ссылка на python3, указывающая на python 3.7 в каталоге bin.

Установите 3.x как версию по умолчанию
Проверьте путь к Python в / usr / bin. Вы можете видеть, что python связан с python 2.7, поэтому выполнение python эквивалентно выполнению python 2.7.

Переименуйте исходную программную ссылку python:

Свяжите python с python3:

В это время проверьте версию Python:

Результатом будет 3.x, что указывает на использование python3.

Настроить yum
После обновления Python, поскольку python по умолчанию указывает на python3, yum нельзя использовать в обычном режиме. Вам необходимо отредактировать файл конфигурации yum:

Перевод Linux Daemon HOWTO

Как написать демон в Linux

Версия 1.0, май 2004
------------------------------------------------------------ ------------
В этом документе рассказывается о том, как писать демонов в Linux с использованием GCC. Для полного понимания этого документа необходимы знание Linux и языка программирования C. Права на этот документ в терминах лицензии BSD принадлежат Девину Ватсону.
------------------------------------------------------------ ------------

1. Введение: что есть демон?

3. Планирование вашего демона
* 3.1 Что необходимо сделать?
* 3.2 Насколько интерактивные?

4. Базовая структура демона
* 4.1 Ответвление от родительского процесса
* 4.2 Изменение маски файла (Umask)
* 4.3 Открытие журналов на запись
* 4.4 Создание уникального ID сессии (SID)
* 4.5 Изменение рабочего каталога
* 4.6 Закрытие стандартных файловых дескрипторов

5. Реализация кода демона
* 5.1 Инициализация
* 5.2 Большой Цикл

6. Собираем все вместе
* 6.1 Законченный пример


1. Введение: что есть демон?

Создание демона в Linux включает в себя соблюдение набора специфических правил в определенном порядке. Знание того как они работают поможет вам понять как демоны работают в пространстве пользователя Linux, но при этом также могут использовать вызовы ядра. На самом деле, совсем немного демонов взаимодействует с модулями ядра, которые работают с аппаратными устройствами, такими как платы внешних контроллеров, принтеров и КПК. Они являются одним из фундаментальных строительных блоков в Linux и дают невероятные гибкость и производительность системе в целом.

В процессе повествования будет разработан очень простой демон на языке C. По мере продвижения по документу будет добавляться все больше кода, показывающего правильный порядок разработки, необходимый для запуска и работы демона.

Прежде всего, для разработки демонов в вашей Linux системе должны быть установлены следующие пакеты:

* GCC 3.2.2 или выше
* библиотеки и заголовочные файлы для разработки в Linux

Если в вашей системе они еще не установлены (что вряд ли, но все равно проверьте), то они понадобятся вам для реализации примеров из этого документа. Чтобы узнать версию установленного в вашей системе GCC, скомандуйте:

3. Планирование вашего демона

3.1 Что необходимо сделать?
Демон должен делать только одну вещь и делать ее хорошо. Эта одна вещь может быть такой же сложной как управление сотнями почтовых ящиков во множестве доменов или такой же простой как формирование отчета и вызов sendmail для оправки этого отчета админу.

В любом случае вы должны хорошо представлять себе то, что должен делать ваш демон. Если планируется взаимодействие с другими демонами, разрабатываемыми и вами, и не вами, то это тоже необходимо учитывать при планировании.

3.2 Насколько интерактивные?
Демоны не должны общаться с пользователем напрямую через терминал. На самом деле, демон вообще не должен напрямую общаться с пользователем. Все общение должно производиться через определенный интерфейс (который может позволять, а может и не позволять запись), который может быть сложным как GTK+ GUI или простым как набор сигналов.


4. Базовая структура демона

Когда демон запускается, он выполняет некоторую низкоуровневую работу для подготовки себя к основной работе. Первая включает в себя несколько шагов:

* Отделение (ответвление, fork) от родительского процесса
* Изменение файловой маски (umask)
* Открытие любых журналов на запись
* Создание уникального ID сессии (SID)
* Изменение текущего рабочего каталога на безопасное место
* Закрытие стандартных файловых дескрипторов
* Переход к коду собственно демона

4.1 Отделение от родительского процесса
Демон запускается либо самой системой, либо пользователем в терминале или скрипте. Во время запуска его процесс ничем не отличается от любого другого процесса в системе. Чтобы сделать его по-настоящему автономным, нужно создать дочерний процесс, в котором будет выполняться код демона. Это называется форком и для этого используется функция fork():


Отметим здесь проверку успешного завершения вызова fork(). При разработке демона необходимо делать код максимально стабильным. На самом деле, большую часть всего кода демона составляют именно проверки на ошибки.

Функция fork() возвращает либо id дочернего процесса (PID, не равный нулю), либо -1 в случае ошибки. Если процесс не может породить потомка, то демон должен завершиться прямо здесь.

Если получение PID от fork() совершилось успешно, то родительский процесс должен изящно завершиться. Это может показаться странным для всех, кто такого еще не видел, но после ответвления дочерний процесс продолжает выполнение остального кода с этого места.

4.2 Изменение файловой маски (Umask)
Чтобы иметь возможномть писать в любые файлы (включая журналы), созданные демоном, файловая маска (umask) должна быть изменена так, чтобы они могли быть записаны или прочитаны правильным образом. Это похоже на выполнение umask из командной строки, но мы прагматично делаем это здесь при помощи функции umask():


Через установку umask в 0 мы получим полный доступ к файлам, созданным демоном. Даже если вы не планируете использовать какие-либо файлы вообще, установка umask остается хорошей идеей просто на случай доступа к файлам на файловой системе.

4.3 Открытие журналов на запись
Эта действие опционально, но все-таки рекомендуется открыть где-нибудь в системе файл журнала на запись. Это можно сделать даже только для того, чтобы вы имели возможность посмотреть на отладочную информацию от демона.

4.4 Создание уникального ID сессии (SID)
С этого места для нормальной работы дочерний процесс должен получить уникальный SID от ядра. Иначе дочерний процесс станет сиротой. Тип pid_t, объявленный в предыдущем разделе, также используется для создания нового SID для дочернего процесса:


Как видим, функция setsid() возвращает данные того же типа что и fork(). Чтобы проверить что функция создала SID для дочернего процесса мы можем использовать аналогичную процедуру проверки на ошибки.

4.5 Изменение рабочего каталога
Текущий рабочий каталог нужно сменить на некоторое место, гарантированно присутствующее в системе. Поскольку многие дистрибутивы Linux не полностью следуют стандарту иерархии файловой системы Linux (FHS, Filesystem Hierarchy Standard), то в системе гарантированно присутствует только корень файловой системы (/). Сменить каталог можно при помощи функции chdir():


И снова мы видим здесь код обработки ошибок. Функция chdir() при ошибке возвращает -1, так что не забывайте проверять возвращаемое ею значение после смены каталога.

4.6 Закрытие стандартных файловых дескрипторов
Одним из последних шагов в стартовой настройке демона является закрытие стандартных файловых дескрипторов (STDIN, STDOUT, STDERR). Поскольку демон не может использовать терминал, эти файловые дескрипторы излишни и создают угрозу безопасности. Закрыть их можно при помощи функции close():


Использование определенных для файловых дескрипторов констант является хорошей идеей, поскольку улучшает переносимость.


5. Разработка кода демона

5.1 Инициализация
На данном этапе вы уже в основном сообщили Linux о том что вы демон, так что сейчас самое время написать код самого демона. Инициализация является первым шагом на этом пути. Поскольку возможно существование множества разных функций, которые могут быть вызваны здесь для настройки вашего демона, я не буду углубляться в этот вопрос.

Важный момент здесь в том, что при инициализации чего-нибудь в демоне необходимо применять те же методы обнаружения и обработки ошибок. Будьте болтливы ("verbose") насколько это возможно при записи в syslog или в ваши собственные журналы. Отладка демона может затрудниться при недостатке информации о его состоянии.

5.2 Большой Цикл
Основной код демона обычно находится внутри бесконечного цикла. Технически это не бесконечный цикл конечно, но он организован как бесконечный:


Типичный цикл обычно является циклом while, который имеет бесконечное условие завершения с вызовом sleep при необходимости выполнения через фиксированные интервалы.

Представьте себе это стуком сердца: когда ваше сердце сжимается, оно выполняет несколько задач, затем ожидает следующего сжатия. Многие демоны следуют этой методологии.

6. Собираем все вместе

6.1 Законченный пример
Приведенное ниже является законченным примером демона и иллюстрирует все шаги, необходимые для запуска и работы. Для его выполнения просто скимпилируйте при помощи gcc и запустите на выполнение из командной строки. Для завершения выясните его PID и воспользуйтесь командой kill.

Я также задействовал подходящие заголовочные файлы для взаимодействия с syslog'ом, использование которого рекомендуется как минимум для записи в журнал информации о запуске/останове/паузе/завершении, в дополнение к использованию ваших собственных журналов через вызовы функций fopen()/fwrite()/fclose().


Вы можете использовать этот скелет для разработки ваших собственных демонов. Не забывайте вести журналы событий (или используйте возможности syslog) и кодируйте надежно, кодируйте надежно, кодируйте надежно!

Вы можете запустить свой php-скрипт из командной строки (например, bash), используя

nohup php myscript.php &

& ставит ваш процесс в фоновом режиме.

Изменить:
Да, есть недостатки, но их невозможно контролировать? Это просто неправильно.
Простой kill processid это остановит. И это по-прежнему лучшее и простое решение.


Это не приведет к перезапуску демона в случае сбоя, а простого способа управления демоном вообще нет.

эй, ребята . мне кажется, nohup и & делает то же самое: отсоединяет запущенный процесс от текущей оболочки. Зачем мне они оба? Можно не вобще php myscript.php & или nohup myscript.php ?? Спасибо

Если скрипт пишет в stdout (через echo или var_dump), вы можете уловить эту информацию с помощью такого файла журнала: nohup php myscript.php > myscript.log &

Другой вариант - использовать Upstart . Первоначально он был разработан для Ubuntu (и по умолчанию поставляется в комплекте), но предназначен для использования во всех дистрибутивах Linux.

Этот подход аналогичен Supervisord и daemontools в том, что он автоматически запускает демон при загрузке системы и возрождается после завершения сценария.

Как это настроить:

Создайте новый файл сценария в /etc/init/myphpworker.conf . Вот пример:

Запуск и остановка вашего демона:

Проверьте, запущен ли ваш демон:

Спасибо

Большое спасибо Кевину ван Зонневельду , у которого я научился этой технике.


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

Sudo "запуск службы myphpworker" у меня не работал. Я использовал "sudo start myphpworker", и он отлично работает

С новым systemd вы можете создать сервис.

Вы должны создать файл или символическую ссылку на /etc/systemd/system/ , например. myphpdaemon.service и разместите контент, подобный этому, myphpdaemon будет именем службы:

Вы сможете запускать, получать статус, перезапускать и останавливать службы с помощью команды

Если ваша процедура PHP должна выполняться один раз в цикле (например, дайджест), вы можете использовать сценарий оболочки или bash, который будет вызываться в служебный файл systemd, а не напрямую PHP, например:

Если вы выбрали эту опцию, вы должны изменить KillMode на mixed процессы, bash (основной) и PHP (дочерний) будут убиты.

This method also is effective if you're facing a memory leak.

Note: Every time that you change your "myphpdaemon.service" you must run `systemctl daemon-reload', but do worry if you not do, it will be alerted when is needed.

@LeandroTupone MySQL и Memcached были демонстрацией того, как использовать зависимости служб, в которых нет необходимости.

Если можете - возьмите копию Advanced Programming in the UNIX Environment . Вся глава 13 посвящена программированию демонов. Примеры приведены на C, но все функции, которые вам нужны, имеют оболочки на PHP (в основном расширения pcntl и posix ).

В двух словах - написание демона (это возможно только в ОС на базе * nix - Windows использует службы) выглядит так:

Кроме того, поскольку вы используете PHP, будьте осторожны с циклическими ссылками, поскольку сборщик мусора PHP до PHP 5.3 не имеет возможности собирать эти ссылки, и процесс будет утечкой памяти, пока в конечном итоге не выйдет из строя.

Спасибо за информацию. Похоже, программа демона libslack в значительной степени выполняет всю подготовительную работу, о которой вы упомянули. Я думаю, что пока буду придерживаться этого, пока не найду другие хорошие альтернативы.

Нашел этот пост, ожидал, что код для копирования и вставки в старое дрянное приложение, которое не может закрыть stdin и т. Д., Был разочарован. :п

Я запускаю большое количество демонов PHP.

Я согласен с вами, что PHP - не лучший (или даже хороший) язык для этого, но демоны разделяют код с веб-компонентами, так что в целом это хорошее решение для нас.

Для этого мы используем daemontools. Он шустрый, чистый и надежный. Фактически мы используем его для запуска всех наших демонов.

РЕДАКТИРОВАТЬ: краткий список функций.

  • Автоматически запускает демон при перезагрузке
  • Автоматический перезапуск dameon в случае сбоя
  • За вас обрабатывается ведение журнала, в том числе опрокидывание и обрезка.
  • Интерфейс управления: svc и svstat
  • Совместимость с UNIX (возможно, не для всех)


Я бы порекомендовал самый простой метод (на мой взгляд, экран), а затем, если вам нужно больше возможностей или функций, перейдите к более сложным методам.

Есть несколько способов решить эту проблему.

Честно говоря, я думаю, что лучше всего создать процесс Дэймона с помощью nohup. nohup позволяет команде продолжать выполнение даже после выхода пользователя из системы:

Однако есть очень серьезная проблема. Как вы сказали, диспетчер памяти PHP - это полный мусор, он был построен с предположением, что сценарий выполняется только в течение нескольких секунд, а затем существует. Ваш PHP-скрипт начнет использовать ГИГАБАЙТЫ памяти всего через несколько дней. Вы ДОЛЖНЫ ТАКЖЕ создать cron-скрипт, который запускается каждые 12 или, может быть, 24 часа, который убивает и повторно запускает ваш php-скрипт следующим образом:

Идея $ lock заключается в том, что сценарий PHP может открывать файл с помощью fopen ("file", "w") ;. Только один процесс может иметь блокировку записи в файл, поэтому с ее помощью вы можете убедиться, что работает только одна копия вашего PHP-скрипта.

Кевин ван Зонневельд написал об этом очень хорошую подробную статью , в своем примере он использует System_Daemon пакет PEAR (последняя дата выпуска - 02.09.2009).

Это объектно-ориентированная библиотека демонов. Он имеет встроенную поддержку таких вещей, как ведение журнала и восстановление после ошибок, а также поддержка создания фоновых рабочих.

Недавно мне понадобилось кроссплатформенное решение (Windows, Mac и Linux) для решения проблемы запуска PHP-скриптов в качестве демонов. Я решил проблему, написав собственное решение на C ++ и сделав двоичные файлы:

Полная поддержка Linux (через sysvinit), но также запущены службы Windows NT и Mac OSX.

Если вам просто нужен Linux, то пара других решений, представленных здесь, работают достаточно хорошо и, в зависимости от вкуса. В наши дни также существуют Upstart и systemd, у которых есть резервные копии сценариев sysvinit. Но половина смысла использования PHP заключается в том, что он кроссплатформенный по своей природе, поэтому код, написанный на этом языке, имеет довольно хорошие шансы работать везде как есть. Недостатки начинают проявляться, когда на сцену попадают определенные внешние нативные аспекты уровня ОС, такие как системные службы, но вы столкнетесь с этой проблемой с большинством языков сценариев.

Со временем PHP также стал лучше справляться с проблемами утечки памяти. Вы все равно должны быть осторожны (синтаксический анализатор DOM XML все еще имеет тенденцию к утечкам), но в наши дни я редко вижу неконтролируемые процессы, а трекер ошибок PHP работает довольно тихо по сравнению с темами прошлого.

Читайте также: