- Выполнение скрипта при запуске или выключении linux
- Консольный вариант.
- Графический вариант.
- Запуск скрипта при выключении компьютера
- Системный интегратор
- init.d Скрипты автозапуска при включении, выключении системы.
- Выполнение скрипта при включении/отключении сети
- Systemd, интерактивные скрипты и таймеры
- Введение
- Зачем нужны target
- Пример target при включении(обзор возможности) с запуском интерактивного скрипта
- Подготовка прошивки к запуску
- Сервис с таймером для logrotate
- Интерактивный скрипт при выключении и свой таргет выключения
Выполнение скрипта при запуске или выключении linux
Если на вопрос: «как добавить программу в автозагрузку?» — начинающие пользователи находят ответ достаточно быстро, то вопрос о запуске скрипта, при выключении/перезагрузки, ставит их в тупик. В статье будет описан стандартный способ для автоматического выполнения команд при включении и выключении linux, а также более простой способ для пользователей, у которых установлен gdm и графический интерфейс, например ubuntu.
Консольный вариант.
Немного теории.
Следует знать, что в Linux существует 7 уровней запуска. Однако, использоваться могут только 6.
Как у всех уважающих себя программ отсчёт начинается с 0-ля.
0 — Остановка или выключение системы.
1 — Однопользовательский режим.
2 — Многопользовательский режим, но без поддержки сети.
3 — Тоже самое, но с сетью.
4 — Добавили для красоты Не используется.
5 — Графический режим с загрузкой X сервера.
6 — Перезагрузка.
Если перейти в папку /etc (В некоторых дистрибутивах /etc/rc.d) то можно увидеть папки с 7-мью уровнями запуска.
Например при выключении компьютера, выполнятся все скрипты из папки rc0.d
Тут следует остановится по подробнее. Дело в том, что самих скриптов (а точнее сценариев) в этой папке нету, а есть только ссылки на файлы, которые лежат в папке /etc/init.d. Эти сценарии выполняют различные задачи, в зависимости от параметра start или stop (например /etc/init.d/reboot start и /etc/init.d/reboot stop это разные команды, а /etc/init.d/reboot вообще не будет работать). Если в ссылке стоит первая буква S, то значит сценарию подаётся параметр start, а если стоит буква K(от слова kill), то параметр stop. Цифра после буквы обозначает порядок выполнения сценария.
Например, на выше вставленном скриншоте вначале выполниться команда /etc/init.d/hddtemp stop, а уже позже /etc/init.d/networking start.
Хватит теории. Переходим к практике.
Для того, чтобы добавить команду в автозагрузку, достаточно поместить её в файл /etc/rc.local.
В этой части статьи в качестве редактора будет использоваться nano, но вы можете пользоваться своим любимым редактором, например gedit.
И помещаем наши команды чуть выше строчки с exit 0.
Для того, что бы команды выполнялись перед выключением или перезагрузкой нам нужно создать сценарий в папке /etc/init.d
Вставляем следующий код:
Если будет подаваться только один сигнал, то просто закомментируйте строку поставив в начале команды знак #
Например
Теперь делаем файл исполняемым:
Создать ссылки можно вручную, но проще это сделать через команду update-rc.d
Например:
Точки важны (обе). Исследуя просторы интернета, у меня сложилось впечатление, что синтаксис этой программы иногда меняется. Актуальные примеры можно посмотреть по команде «man update-rc.d». Примеры будут в низу.
Эта команда создаст по 2 ссылки в каталогах /etc/rc0.d (второе число в команде) и /etc/rc6.d (третье число в команде). Причём вначале будет выполняться сценарий с параметром stop (т.к. стоит 1), а уже потом с параметром start (т.к. стоит 20).
Если второй параметр не нужен, то можно выполнить команду:
Советую ставить приоритет повыше (т.е. число после start или stop должно быть маленьким), желательно меньше 20. В обратном случае у меня иногда зависал компьютер при попытке перезагрузиться.
Для пользователей ubuntu, да и многих других современных дистрибутивов с gdm можно воспользоваться…
Графический вариант.
Что касается автозагрузки то можно воспользоваться способом описанным здесь.
Или просто открыть «автоматически запускаемые приложения» командой:
Для выполнения скрипта при выключении компьютера, помещаем его в файл /etc/gdm/PostSession/Default
Источник
Запуск скрипта при выключении компьютера
Задача: Сделать автоматический запуск нашего скрипта перед перезагрузкой и выключением компьютера.
Для примера создадим скрипт выполняющий обновление системы перед выключением.
Для управления загрузкой и работой сервисов в kubuntu начиная с версии 15.04 используется systemd.
Systemd хранит свои юниты в папке /etc/systemd/system/ туда мы и положим свой новый юнит.
Создаем файл сервиса с именем poweroff_dist_upgrade.service
sudo nano /etc/systemd/system/poweroff_dist_upgrade.service
добавляем в него содержимое
[Unit]
Description=Dist Upgrade before restart and power off
After=systemd-user-sessions.service
[Install]
WantedBy=multi-user.target reboot.target poweroff.target
Unit — общая информация.
Description — описание сервиса.
After — задаёт порядок загрузки. В этом случае после старта сессии пользователя.
Service — содержит информацию о службе
ExecStop — Какой скрипт будет выполнен
Type — Типы службы. oneshot для скриптов, которые выполняют одно задание и завершаются
Install — когда юнит должен быть активирован.
multi-user.target или runlevel3.target соответствует runlevel=3 «Многопользовательский режим без графики»
Назначаем права на запуск
sudo chmod +x /etc/systemd/system/poweroff_dist_upgrade.service
Создаем сам скрипт который будет выполняться
sudo nano /usr/local/bin/distupgrade.sh
#!/bin/bash
apt update && apt dist-upgrade -f -y && apt autoremove -y
echo ‘Обновление ‘$(date ‘+%m.%d %H:%M’) >> /var/log/dist-upgrade_before_power_off.log
exit 0
Делаем скрипты выполняемым
sudo chmod +x /usr/local/bin/distupgrade.sh
Перезагружаем systemd для поиска новых или измененных юнитов:
sudo systemctl daemon-reload
Источник
Системный интегратор
init.d Скрипты автозапуска при включении, выключении системы.
Скрипты запускаемых служб в Linux Ubuntu располагаются в /etc/init.d
Для того, чтобы скрипт запускался автоматически во время запуска системы, надо создать символическую ссылку на скрипт и разместить её в каталоге /etc/rc.d/rcN.d, где N уровень выполнения скрипта.
Уровень 0
остановка системы (halt) — работа системы должна быть прекращена.
Уровень 1
однопользовательский режим работы — консоль восстановления.
Уровень 2
многопользовательский режим — пользователи могут работать на разных терминалах.
Уровень 3
многопользовательский сетевой режим — осуществляется настройка сети и запускаются сетевые службы.
Уровень 4
практически не используется.
Уровень 5
запуск графической подсистемы X11 — вход в систему осуществляется уже в графическом режиме.
Уровень 6
перезагрузка системы — останавливаются все запущенные программы и производится перезагрузка.
Чаще всего во время загрузки системы используются уровни загрузки 3 или 5.
Имя ссылки в каталоге /etc/rc.d/rcN.d имеет особый смысл, например: если сыылки /etc/rc.d/rcN.d/@K99cpu_t и /etc/rc.d/rcN.d/@S00cpu_t указывают на один и тот же файл /etc/init.d/cpu_t, то скрипт @K99cpu_t будет выполнять в cpu_t блок кода, соответствующий останову системы, а скрипт @S00cpu_t будет выполнять в cpu_t блок кода, соответствующий старту системы, Две цифры в начале имени символической ссылки определяют порядок запуска скриптов в каталоге /etc/rc.d/rcN.d.
Cкрипт запуска должен иметь специальный формат, например такой:
Главное тут в следующем, во первых скрипт должен иметь как минимум 3 возможных ключа запуска, это: start, stop, restart, поскольку именно эти основные команды используются для запуска, останова и перезапуска. Плюс ко всему к этому в самом начале файла пишутся те самые заветные цифры отвечающие за последовательность запуска:
# chkconfig: — 98 02
Где 98 это номер в последовательности запуска, а 02 это номер последовательности останова.
То есть, проще говоря, этот скрипт запуститься 98мым в последовательности очередей, а будет остановлен 2рым.
Итак для того чтоб добавить скрипт и добавить его в автозагрузку надо произвести следующую последовательность действий:
1. Создать исполняемый скрипт по шаблону приведёному выше, заменив исполняемый_файл именем файла который надо запустить.
2. Разместить исполняемый скрипт в /etc/rc.d/init
3. Выполнить команду chkconfig —add исполняемый_скрипт
4. Выполнить команду setup или servicevonf (в зависимости от того работаете вы в графическом режиме или консоли) и выбрать службу, которая будет носить имя исполняемый_скрипт.
Выполнение скрипта при включении/отключении сети
Есть директория /etc/network/ с поддиректориями if-down.d, if-pre-up.d, if-post-down.d, if-up.d. Если разместить скрипт в одной из этих поддиректорий, то он будет выполняться соответственно при выключении, перед включением, после выключения или при включении сети.
Другой способ — указать в файле /etc/network/interfaces одну из следующих директив: up, pre-up, post-up, down, pre-down, post-down. Например, строка
после включения сети выполнит скрипт script.sh. Подробнее можно почитать в man interfaces.
В любом случае на скрипт должны быть установлены права, разрешающие выполнение, иначе он не сможет запуститься.
Источник
Systemd, интерактивные скрипты и таймеры
Введение
При разработке под linux возникают задачи создания интерактивных скриптов, выполняемых при включении или завершении работы системы. В system V это делалось легко, но с systemd вносит коррективы. Зато оно умеет свои таймеры.
Зачем нужны target
Часто пишут, что target служат аналогом runlevel в system V -init. В корне не согласен. Их больше и можно разделять пакеты по группам и, к примеру, запускать одной командой группу сервисов, выполнять дополнительные действия. Кроме того, у них нет иерархии, только зависимости.
Пример target при включении(обзор возможности) с запуском интерактивного скрипта
Описание самого target:
Данный target запустится, когда будет запущен multi-user.target и вызовет installer.service. При этом таких сервисов может быть несколько.
И наконец, пример выполняемого скрипта:
Самое главное — выбрать final.target — target, к которому система должна придти при запуске. В процессе запуска systemd пройдёт по зависимостям и запустит всё нужное.
Выбрать final.target можно разными способами, я использовал для этого опцию загрузчика.
Итоговый запуск выглядит так:
- Стартует загрузчик
- Загрузчик начинает запуск прошивки, передавая параметр final.target
- Systemd начинает запуск системы. Последовательно идёт к installer.target или work.target от basic.target через их зависимости (например,multi-user.target). Последние и приводят систему к работе в нужном режиме
Подготовка прошивки к запуску
При создании прошивок всегда возникает задача восстановления состояния системы при старте и его сохранении при выключении. Под состоянием подразумеваются конфигурационные файлы, дампы базы данных, настройки интерфейсов и тд.
Systemd запускает процессу в одном таргете параллельно. Есть зависимости, которые позволяют определить последовательность запуска скриптов.
- Система стартует
- Запускается сервис settings_restore.service.Он проверяет наличие файла settings.txt в разделе с данными. Если его нет, то на его место кладётся эталонный файл.Далее происходит восстановление настроек системы:
- пароля администратора
- hostname,
- часового пояс
- локаль
- Определение, весь ли носитель используется. По умолчанию размер образа небольшой — для удобства копирования и записи на носитель. При старте проверяется — есть ли ещё неиспользуемое место. Если есть — диск переразбивается.
- Генерация machine-id из MAC-адреса. Это важно для получения одного и того же адреса по DHCP
- Настройки сети
- Ограничивается размер логов
- Подготавливается к работа внешний диск(если включена соответствующая опция и диск новый)
- Запускаться postgresq
- запускается сервис restore. Он нужен для подготовки самого zabbix и его базы данных:
- Проверяется, есть ли уже база данных zabbix. Если нет — создается из инициализирующих дампов(идут в поставке zabbix)
- создается список часовых поясов (нужно для их отображения в web-интерфейсе)
- Находится текущий IP, он выводится в issue (приглашение для входа в консоли)
- Меняется приглашение — появляется фраза Ready to work
- Прошивка готова к работе
Важны файлы сервисов, именно они выставляют последовательность их запуска
Как видно, я поставил зависимости, что бы сначала отработал мой скрипт, а только потом поднималась сеть и стартовала СУБД.
И второй сервис(подготовка zabbix)
Здесь немного сложнее.Запуск так же в multi-user.target, но ПОСЛЕ запуска СУБД postgresql и моего setting_restore. Но ПЕРЕД запуском служб zabbix.
Сервис с таймером для logrotate
Systemd может заменить CRON. Серьезно. Причем точность не до минуты, а до секунды(а вдруг понадобится).А можно создать монотонный таймер, вызываемый по таймауту от события.
Именно монотонный таймер, считающий время от запуска машины, я и создал.
Для этого потребуется 2 файла
logrotateTimer.service — собственно описание сервиса:
Всё просто — описание команда запуска.
Второй файл logrotateTimer.timer — вот он и задает работу таймеров:
- описание таймера
- Время первого запуска, начиная от загрузки систем
- период дальнейших запусков
- Зависимость от службы таймеров.Фактически, это строка и делает таймер
Интерактивный скрипт при выключении и свой таргет выключения
В другой разработке мне пришлось делать более сложный вариант выключения машины — через собственный таргет, что бы выполнить множество действий. Обычно рекомендуется создать сервис oneshot с опцией RemainAfterExit, но это не дает создать интерактивный скрипт.
А дело в том, что команды, запускаемые опцией ExecOnStop выполняются вне TTY! Проверить просто — вставьте команду tty и сохраните её вывод.
Поэтому я реализовал выключение через свой таргет. На 100% правильность не претендую, но это работает!
Как это делалось(в общих чертах):
Создал таргет my_shutdown.target, который ни от кого не зависел:
my_shutdown.target
При переходе в этот таргет(через systemctl isolate my_shutdwn.target), он запускал сервис my_shutdown.service, задача которого простая — выполнить скрипт my_shutdown.sh:
- Внутри этого скрипта я выполняю нужные действия. Можно в таргет добавить много скриптов, для гибкости и удобства:
Примечание. Использование файлов /tmp/reboot и /tmp/shutdown. Нельзя вызвать target с параметрами. Можно только service.
Но я использую target, что бы иметь гибкость в работе и гарантированный порядок выполнения действий.
Однако, самое интересное было потом. Машину же надо выключить/перезагрузить. И тут есть 2 варианта:
- Заменить команды reboot,shutdown и прочие(они все равно являются симлинками на systemctl) на свой скрипт.Внутри скрипта — переход в my_shutdown.target. А скрипты внутри таргета потом вызывают напрямую systemctl, например, systemctl reboot
- Более простой, но мне не нравящийся вариант. Во всех интерфейсах вызывать не shutdown/reboot/прочие, а напрямую вызывать таргет systemctl isolate my_shutdown.target
Я выбрал первый вариант. В systemd reboot(как и poweroff) являются симлинками на systemd.
Поэтому их можно заменить на свои скрипты:
reboot
Источник