Страница 1 из 1

Создание сервиса в Linux Debian

Добавлено: 28 фев 2017, 13:48
xor
Источник: http://www.it-simple.ru/?p=7561

Как создать свою службу в Linux

Три простых шага:
  1. Создаём скрипт для управления сервисом, в специальном формате.
  2. Помещаем его в хранилище сервисных скриптов. Это каталог /etc/init.d
  3. Обрабатываем скрипт специальной утилитой update-rc.d (или insserv)
Шаг 1. Создание скрипта

Вот шаблон, чтобы не запутаться:

Код: Выделить всё

#!/bin/sh

### BEGIN INIT INFO
# Provides:          scriptName
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Example my init script
# Description:       This file should be used to construct scripts to be placed in /etc/init.d
### END INIT INFO

# Здесь должен находиться основной код.
# Этот код должен обрабатывать команды start, stop и restart, переданные скрипту.
# Использование других команд не возбраняется.
# Для наглядного примера можно посмотреть любой файл из /etc/init.d/
Шаблон от разработчиков находится по адресу /etc/init.d/skeleton

Обратите внимание на блок, ограниченный метками [### BEGIN INIT INFO] и [### END INIT INFO].
Этот блок полностью закомментирован, то есть при выполнении скрипта его содержимое игнорируется. Однако, он содержит инструкции для утилиты update-rc.d, которая прочитает их, поймёт и раскидает ссылки на этот скрипт по уровням запуска системы.

Подробнее про процессы, службы, уровни запуска и устройство каталогов запуска можно прочитать здесь.

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

### BEGIN INIT INFO - метка начала списка инструкций
### END INIT INFO - метка конца списка инструкций

Все строки между ними должны быть в формате:
# Инструкция: арг1 [арг2...]

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

Список инструкций
Данный список взят по одной из ссылок в конце записи, описания нуждаются в доработке
Provides Описывает предоставляемые этим скриптом объекты (арг1, агр2, ...) таким способом, что, когда скрипт запускается с аругментом start, данные объекты считаются существующими, и, следовательно, другие скрипты в init, которые требуют существование этих объектов, смогут запуститься на более поздней стадии. Обычно, можно использовать имя скрипта в качестве объекта, но так же можно использовать имя сервиса, которую он заменяет. Виртуальные объекты тут не указываются. Они определены вне скриптов init.d
Required-Start Задаёт объекты, которые должны существовать, чтобы запустить скрипт. Можно использовать при необходимости виртуальные объекты, как описано ниже. Если объекты не указаны, то этот скрипт может быть запущен сразу после старта, не требуя подключенных локальных файловых систем, запущенного системного журнала и т.д.
Required-Stop Задаёт объекты, используемые сервисом, предоставляемой скриптом. Объект, предоставляемый этим скриптом должен завершиться до завершения перечисленных здесь объектов, чтобы избежать конфликтов. Обычно, здесь указывают те же объекты, что и в Required-Start
Should-Start Задаёт объекты, которые, если существуют, должны должны быть запущены перед сервисом, предоставляемым данным скриптом. Это допускает слабые зависимости, которые не приводят сервис к ошибке, если объекты не доступны. Можно использовать при необходимости виртуальные объекты, как описано ниже.
Should-Stop Задаёт объекты, если существуют должны быть остановлены уже после данного сервиса. Обычно, здесь указывают те же объекты, что и в Should-Start
Default-Start // Default-Stop Задаёт уровни запуска, на которых скрипт должен быть запущен (остановлен) по умолчанию. Например, если сервис должен быть запущен на только уровнях 3, 4 и 5, укажите "Default-Start: 3 4 5" и "Default-Stop: 0 1 2 6".
Short-Description Задаёт короткое описание действия скрипта. Ограничено одной строкой.
Description Задаёт более подробное описание действия скрипта. Может быть в несколько строк, в этом случае, каждая строка описания должна начинаться с символа # с последующим знаком табуляции или как минимум 2-мя символами пробела. Описание заканчивается перед линией, не совпадающим с этим условием.
X-Start-Before // X-Stop-After Задаёт обратные зависимости, которые значат то же, как если бы они были указаны в should-start и should-stop в пакетах, указанных тут.
Уровни запуска определяют, в какие из каталогов /etc/rcX.d будут помещены ссылки на текущий скрипт.

Для отслеживания зависимостей важны инструкции Provides, Required- и Should-. Остальные не используются. На основе зависимостей утилита update-rc.d (или insserv) упорядочивает скрипты в каталоге определённого уровня запуска (/etc/rcX.d).

Список виртуальных объектов
Та же хрень, что и с предыдущим списком
$local_fs Все локальные фаловые системы подключены. Все скрипты, которые производят запись в /var/ должны зависеть от этого, если они уже не зависят от $remote_fs
$network низкоуровневая сеть, т.е. сетевые карты, может подразумеваться PCMCIA запущеной
$named Демоны, которые могут предоставлять разрешение доменных имён предполагаются запущенными. Например, DNS, NIS+ или LDAP
$portmap Демоны, предоставляющие сервис SunRPC/ONCRPC portmapping как указано в 1833 (если они есть)
$remote_fs Все файловые системы подключены. Скрипты, которые должны быть запущены во время остановки системы до того, как всем процессам будет отправлен сигнал уничтожения, должны зависеть от $remote_fs.
$syslog системный журнал функционирует
$time установленно корректное системное время, например, ntp или rdate, или RTC
$all Запускает скрипт как можно позже, после всех

Шаг 2+3. Оформление скрипта в качестве службы
Допустим, имя нашего самописного скрипта somestuff. Именно так, somestuff, без всяких расширений.
Делаем его исполняемым:
chmod +x ./somestuff

Копируем в хранилище сервисных скриптов:
cp ./somestuff /etc/init.d

И делаем прописку в каталогах уровней запуска:
update-rc.d somestuff defaults

Полный путь давать не надо, только имя в /etc/init.d/
Для выписки (удаления всех симлинков на этот скрипт из всех каталогов уровней запуска) делаем:
update-rc.d -f somestuff remove

Исходный скрипт /etc/init.d/somestuff при этом не удаляется.