LinuxRuLinux без лишней теории
systemd

systemctl в Linux: управление службами и автозагрузкой

Редакция LinuxRu7 мин чтенияИнструкции

systemctl управляет службами systemd: start и stop запускают и останавливают службу, systemctl enable добавляет её в автозагрузку, а status показывает состояние и последние строки журнала. Ниже все основные команды с примерами, шпаргалка, создание своего unit-файла и пользовательские службы.

systemctl в Linux: управление службами и автозагрузкой
Фото: Software: systemd developers Screenshot: VulcanSphere, LGPL, Wikimedia Commons
Содержание
  1. Что такое юнит
  2. Запуск и остановка
  3. Автозагрузка
  4. Списки служб
  5. Шпаргалка
  6. Журнал службы
  7. Свой unit-файл
  8. Изменить службу
  9. Службы пользователя
  10. Частые вопросы

systemctl и юниты: с чем вы работаете

systemctl - основная команда для управления systemd, системой инициализации, которая стоит в Ubuntu, Debian, Fedora, Arch, openSUSE и большинстве других дистрибутивов. Всё, чем управляет systemd, называется юнитами. Службы имеют суффикс .service, кроме них есть таймеры .timer, сокеты .socket, точки монтирования .mount и цели .target, которые объединяют группы юнитов.

Общий синтаксис: systemctl действие имя. Суффикс .service можно не писать, systemctl status nginx и systemctl status nginx.service равнозначны. Команды, которые что-то меняют, требуют sudo, а просмотр состояния работает и без него.

Одна служба может называться по-разному в разных дистрибутивах. SSH-сервер в Debian и Ubuntu - это ssh, в Fedora и Arch sshd. Apache - apache2 в Debian и Ubuntu и httpd в Fedora. Если не уверены, найдите имя через список юнитов, о нём ниже.

Запуск, остановка и перезапуск службы

# запустить и остановить
sudo systemctl start nginx
sudo systemctl stop nginx

# перезапустить полностью
sudo systemctl restart nginx

# перечитать конфиг без остановки, если служба это умеет
sudo systemctl reload nginx

# reload, а если не поддерживается, то restart
sudo systemctl reload-or-restart nginx

# перезапустить, только если служба уже работает
sudo systemctl try-restart nginx

reload предпочтительнее на рабочих серверах: nginx, Apache или PostgreSQL перечитывают настройки, не обрывая текущие соединения. Перед этим проверьте конфиг встроенной командой самой программы, например sudo nginx -t, иначе служба после перезапуска может не подняться.

Как читать systemctl status

systemctl status nginx

В выводе важны две строки. Loaded показывает, где лежит файл юнита и включена ли автозагрузка: enabled или disabled. Active показывает текущее состояние: active (running) - работает, inactive (dead) - остановлена, failed - упала. Ниже идут главный PID, потребление памяти и последние строки журнала. Если вывод длинный, systemctl открывает его в пейджере, выйти можно клавишей q, а ключ --no-pager печатает всё сразу.

Автозагрузка службы в Linux: systemctl enable и disable

Запуск и автозагрузка - разные вещи. start запускает службу сейчас, но после перезагрузки она не поднимется. enable добавляет её в автозагрузку, но сама по себе не запускает. Чаще всего нужно и то и другое, для этого есть ключ --now.

# включить автозагрузку и сразу запустить
sudo systemctl enable --now nginx

# убрать из автозагрузки и остановить
sudo systemctl disable --now nginx

# проверить состояние одной командой, удобно в скриптах
systemctl is-enabled nginx
systemctl is-active nginx

# запретить запуск совсем, даже как зависимости
sudo systemctl mask cups
sudo systemctl unmask cups

Технически enable создаёт символическую ссылку в каталоге цели из секции [Install] юнита, обычно /etc/systemd/system/multi-user.target.wants/. mask ведёт ссылку на /dev/null, и такую службу не запустить ни вручную, ни через зависимости, пока вы её не размаскируете.

Ответ is-enabled бывает не только enabled или disabled:

  • static - у юнита нет секции [Install], его запускает другой юнит, и включать его не нужно;
  • indirect - включается через другой юнит, часто через сокет или таймер;
  • masked - запуск запрещён;
  • alias - это другое имя для существующего юнита.

Некоторые службы запускаются по требованию через сокет. Например, в свежих Ubuntu SSH по умолчанию активируется через ssh.socket: служба стартует при первом подключении. Тогда автозагрузкой управляет сокет, а не сама служба.

Какие службы запущены и что стоит в автозагрузке

# работающие службы
systemctl list-units --type=service --state=running

# все службы, включённые в автозагрузку
systemctl list-unit-files --type=service --state=enabled

# упавшие юниты
systemctl --failed

# найти службу по части имени
systemctl list-unit-files | grep -i ssh

# показать содержимое юнита со всеми дополнениями
systemctl cat nginx

# от чего зависит служба
systemctl list-dependencies nginx

Разница между командами в том, что list-units показывает юниты, загруженные в память прямо сейчас, а list-unit-files показывает все установленные файлы юнитов и их состояние автозагрузки. Если служба упала, разбор причины по шагам описан в отдельной статье Systemd: как найти и исправить упавшую службу.

Шпаргалка: systemctl команды на каждый день

КомандаЧто делаетНужен sudo
systemctl status имяСостояние, PID, последние строки журналаНет
systemctl start / stop имяЗапустить или остановить сейчасДа
systemctl restart имяПерезапуститьДа
systemctl reload имяПеречитать конфиг без остановкиДа
systemctl enable --now имяДобавить в автозагрузку и запуститьДа
systemctl disable --now имяУбрать из автозагрузки и остановитьДа
systemctl mask / unmask имяЗапретить или разрешить запускДа
systemctl is-enabled имяВключена ли автозагрузкаНет
systemctl edit имяСоздать дополнение к юнитуДа
systemctl daemon-reloadПеречитать файлы юнитов после правкиДа
systemctl --failedСписок упавших юнитовНет
systemctl reboot / poweroffПерезагрузка и выключениеОбычно да

Журнал службы через journalctl

systemctl показывает только последние строки журнала. Полную историю смотрите через journalctl:

# весь журнал службы с текущей загрузки
journalctl -u nginx -b

# следить за новыми строками в реальном времени
journalctl -u nginx -f

# за последний час, только ошибки и серьёзнее
journalctl -u nginx --since "1 hour ago" -p err

# последние 50 строк без пейджера
journalctl -u nginx -n 50 --no-pager

Если журнал разросся до гигабайтов, ограничьте его размер, это описано в статье Журнал systemd занимает диск: настройка journald.

Как создать свою службу: unit-файл с нуля

Допустим, у вас есть скрипт или программа /opt/myapp/server, которая должна работать постоянно, подниматься после перезагрузки и перезапускаться при падении. Создайте файл /etc/systemd/system/myapp.service:

[Unit]
Description=My application server
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
User=myapp
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/server --port 8080
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
# проверить синтаксис юнита
sudo systemd-analyze verify /etc/systemd/system/myapp.service

# перечитать юниты, включить и запустить
sudo systemctl daemon-reload
sudo systemctl enable --now myapp
systemctl status myapp

Пара правил, которые экономят время. В ExecStart пишите полный путь к программе: systemd не использует ваш PATH. Не запускайте службу от root без необходимости, создайте для неё отдельного пользователя, как это сделать, рассказано в статье Пользователи и sudo в Linux. И не забывайте daemon-reload после каждой правки файла, иначе systemd продолжит работать со старой версией.

Не правьте файлы в /usr/lib/systemd/system или /lib/systemd/system: их перезапишет следующее обновление пакета. Для изменения чужой службы используйте sudo systemctl edit имя, а свои юниты храните в /etc/systemd/system.

Как изменить параметры готовой службы через systemctl edit

# создать дополнение override.conf к юниту
sudo systemctl edit nginx

# открыть полную копию юнита для правки
sudo systemctl edit --full nginx

# отменить все локальные изменения
sudo systemctl revert nginx

systemctl edit открывает редактор и сохраняет только ваши изменения в /etc/systemd/system/nginx.service.d/override.conf, после чего сам выполняет daemon-reload. Например, чтобы служба перезапускалась при падении, достаточно дописать:

[Service]
Restart=always
RestartSec=3

Если нужно заменить, а не дополнить параметр, который может повторяться, например ExecStart, сначала сбросьте его пустой строкой ExecStart=, а следующей строкой укажите новое значение. Редактор выбирается переменной SYSTEMD_EDITOR или EDITOR, по умолчанию часто открывается nano.

Пользовательские службы: systemctl --user

Не всё нужно запускать от root. Для своих фоновых программ, например синхронизации или локального сервера разработки, есть пользовательский экземпляр systemd. Юниты кладутся в ~/.config/systemd/user/, а команды выполняются с ключом --user и без sudo:

systemctl --user daemon-reload
systemctl --user enable --now syncthing
systemctl --user status syncthing
journalctl --user -u syncthing -f

# чтобы службы работали без входа в систему
sudo loginctl enable-linger $USER

В секции [Install] пользовательских юнитов обычно пишут WantedBy=default.target. Запуск по расписанию тоже решается средствами systemd через таймеры, сравнение с cron есть в статье Cron в Linux: crontab, синтаксис и systemd timers. Все параметры команды описаны в официальном руководстве systemctl.

Частые вопросы

Как добавить службу в автозагрузку в Linux?

Выполните sudo systemctl enable имя_службы. Чтобы служба ещё и запустилась сразу, добавьте ключ --now: sudo systemctl enable --now имя_службы.

Чем systemctl enable отличается от start?

start запускает службу только до перезагрузки. enable добавляет её в автозагрузку, но сам не запускает. Ключ --now объединяет оба действия.

Как посмотреть все службы в автозагрузке?

Командой systemctl list-unit-files --type=service --state=enabled. Работающие сейчас службы покажет systemctl list-units --type=service --state=running.

Что значит static в выводе systemctl is-enabled?

У юнита нет секции [Install], поэтому его нельзя включить напрямую. Его запускает другой юнит как зависимость, и это нормальное состояние.

Почему изменения в unit-файле не применяются?

После правки файла юнита нужно выполнить sudo systemctl daemon-reload, а затем перезапустить службу. Команда systemctl edit делает daemon-reload сама.

Документация и источники

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

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