Рецепт простой.

  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 при этом не удаляется.



imen
2014.03.02 22:02:55
#cid87709

Ответить

Строго говоря, Linux ≠ Ubuntu.
А описываемая задача так вообще решается штатным механизмом (/etc/local.d/).

Гена
2015.07.22 17:55:45
#cid90813

Ответить

Спасибо злобному админу за простое и понятное руководство.

playnet
2015.11.06 12:28:13
#cid91070

Ответить

https://wiki.debian.org/LSBInitScripts
$all
facility supported by insserv to start a script after all the scripts not depending on $all, at the end of the boot sequence. This only work for start ordering, not stop ordering.
так что в Required-Stop указывать нет смысла и наверное даже вредно.

$all Запускает скрипт как можно последним
как можно позже или просто последним, "как можно последним" совершенно некорректно.

Скрипты, которые должны быть запущены во время остановки системы до того, как всем процессам будет отправлен сигнал уничтожения, должны зависеть от $remote_fs.
тут бред какой-то. А если во время остановки они уже остановлены, система поломается? Лучше бы переписать более понятно.

И никто не описывает, как использовать свои provides. Например, описано
Provides: scriptName
а что писать в другие сервисы в Required-Start? scriptName или $scriptName?

imen
2015.11.09 17:40:30
#cid91075

Ответить

#cid90813, Гена

Спасибо злобному админу за простое и понятное руководство.

Руководство не только «простое и понятное», но и устаревшее.

Пользуясь случаем стоит отметить торжество «демократии» в выборах systemd в Демьяне.
И Космонавт сдался, не стал вписываться за альтернативу _системного_ уровня.

ЗЫ: Wiki, даже в реинкарнации документации свободных проектов, увы — далеко не окончательная Истина.

playnet
2015.11.10 12:06:51
#cid91077

Ответить

#cid91075, imen

#cid90813, Гена

Руководство не только «простое и понятное», но и устаревшее.

Много где ещё инит5 + в дебиляне ещё есть возможность снести поттеринг и поставить инит5. Но тенденция печальная, да.

imen
2015.11.10 15:20:45
#cid91080

Ответить

#cid91077, playnet

Много где ещё инит5 + в дебиляне ещё есть возможность снести поттеринг и поставить инит5. Но тенденция печальная, да.

Во-первых, upstart ≠ классический SVR4. Последних представителей классики мы потеряли уже очень давно.
Во-вторых, за исключением специфической ниши встраиваемых систем, и то только в силу ниасиляторства леннарта и для ядра Linux перечень живых-актуальных «много» в студию! Что-то мне подсказывает, что множество сойдётся в одну точку. Gentoo.
И, наконец, в рамках бинарной парадигмы наблюдается дистанция от «заявляется возможность» до практической применимости отклонений от генеральной линии партии.