Рецепт простой.
- Создаём скрипт для управления сервисом, в специальном формате.
- Помещаем его в хранилище сервисных скриптов. Это каталог
/etc/init.d
- Обрабатываем скрипт специальной утилитой 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
при этом не удаляется.
- Закрепление материала: «Делаем сервис для управления iptables»
- Автозагрузка в Debian (/etc/init.d/)
- Ускорение работы Ubuntu. Часть 1. Процессы и демоны
Комментарии
imen
#cid87709
Ответить
Строго говоря, Linux ≠ Ubuntu.
А описываемая задача так вообще решается штатным механизмом (/etc/local.d/).
Гена
#cid90813
Ответить
Спасибо злобному админу за простое и понятное руководство.
playnet
#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
#cid91075
Ответить
#cid90813, Гена
Руководство не только «простое и понятное», но и устаревшее.
Пользуясь случаем стоит отметить торжество «демократии» в выборах systemd в Демьяне.
И Космонавт сдался, не стал вписываться за альтернативу _системного_ уровня.
ЗЫ: Wiki, даже в реинкарнации документации свободных проектов, увы — далеко не окончательная Истина.
playnet
#cid91077
Ответить
#cid91075, imen
Много где ещё инит5 + в дебиляне ещё есть возможность снести поттеринг и поставить инит5. Но тенденция печальная, да.
imen
#cid91080
Ответить
#cid91077, playnet
Во-первых, upstart ≠ классический SVR4. Последних представителей классики мы потеряли уже очень давно.
Во-вторых, за исключением специфической ниши встраиваемых систем, и то только в силу ниасиляторства леннарта и для ядра Linux перечень живых-актуальных «много» в студию! Что-то мне подсказывает, что множество сойдётся в одну точку. Gentoo.
И, наконец, в рамках бинарной парадигмы наблюдается дистанция от «заявляется возможность» до практической применимости отклонений от генеральной линии партии.