Как мне переопределить или настроить службы systemd?

Многие сценарии инициализации sysv использовали соответствующий файл в /etc/default чтобы разрешить администратору настраивать его. Начальные задания могут быть изменены с помощью .override файлы. Как мне переопределить или настроить модули systemd, теперь, когда systemd используется по умолчанию в Ubuntu?

systemd юниты не должны подчиняться файлам в /etc/default. systemd легко настраивается, но требует, чтобы вы знали синтаксис модульных файлов systemd.

Пакеты отправляют единичные файлы, как правило, в /lib/systemd/system/. Это нет подлежит редактированию. Вместо, systemd позволяет переопределять эти файлы, создавая соответствующие файлы в /etc/systemd/system/.

Для данной услуги foo, пакет будет обеспечивать /lib/systemd/system/foo.service. Вы можете проверить его статус с помощью systemctl status foo, или просматривать его журналы с помощью journalctl -u foo. Чтобы переопределить что-то в определении foo, сделай:

sudo systemctl edit foo

Это создает каталог в /etc/systemd/system названный в честь подразделения, и override.conf файл в этом каталоге (/etc/systemd/system/foo.service.d/override.conf). Вы можете добавлять или переопределять настройки с помощью этого файла (или другого .conf файлы в /etc/systemd/system/foo.service.d/). Это также применимо к подразделениям, не связанным с обслуживанием - вы могли бы сделать systemctl edit foo.mount, systemctl edit foo.timer и т.д.

Переопределение аргументов команды

Возьмите getty например, сервис. Допустим, я хочу, чтобы TTY2 автоматически подключался к моему пользователю (это нежелательно, но просто пример). TTY2 управляется getty@tty2 обслуживание (tty2 будучи экземпляром шаблона /lib/systemd/system/getty@service). Чтобы сделать это, я должен изменить getty@tty2 обслуживание.

$ systemctl cat getty@tty2# /lib/systemd/system/getty@.service#  This file is part of systemd.##  systemd is free software; you can redistribute it and/or modify it#  under the terms of the GNU Lesser General Public License as published by#  the Free Software Foundation; either version 2.1 of the License, or#  (at your option) any later version.[Unit]Description=Getty on %IDocumentation=man:agetty(8) man:systemd-getty-generator(8)Documentation=http://0pointer.de/blog/projects/serial-console.htmlAfter=systemd-user-sessions.service plymouth-quit-wait.serviceAfter=rc-local.service# If additional gettys are spawned during boot then we should make# sure that this is synchronized before getty.target, even though# getty.target didn't actually pull it in.Before=getty.targetIgnoreOnIsolate=yes# On systems without virtual consoles, don't start any getty. Note# that serial gettys are covered by serial-getty@.service, not this# unit.ConditionPathExists=/dev/tty0[Service]# the VT is cleared by TTYVTDisallocateExecStart=-/sbin/agetty --noclear %I $TERMType=idleRestart=alwaysRestartSec=0UtmpIdentifier=%ITTYPath=/dev/%ITTYReset=yesTTYVHangup=yesTTYVTDisallocate=yesKillMode=processIgnoreSIGPIPE=noSendSIGHUP=yes# Unset locale for the console getty since the console has problems# displaying some internationalized messages.Environment=LANG= LANGUAGE= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETARY= LC_MESSAGES= LC_PAPER= LC_NAME= LC_ADDRESS= LC_TELEPHONE= LC_MEASUREMENT= LC_IDENTIFICATION=[Install]WantedBy=getty.targetDefaultInstance=tty1

В частности, я должен изменить ExecStart линия, которая в настоящее время является:

$ systemctl cat getty@tty2 | grep Exec     ExecStart=-/sbin/agetty --noclear %I $TERM

Чтобы переопределить это, выполните:

sudo systemctl edit getty@tty2

И добавить:

[Service]ExecStart=ExecStart=-/sbin/agetty -a muru --noclear %I $TERM

Обратите внимание, что:

  1. Я должен был явно очистить ExecStart перед повторной настройкой, поскольку это аддитивная настройка, аналогичная After, Environment (в целом, а не для каждой переменной) и EnvironmentFile, и в отличие от переопределения настроек, таких как RestartSec или Type. ExecStart может иметь несколько записей только для Type=oneshot услуги.
  2. Я должен был использовать правильный заголовок раздела. В исходном файле, ExecStart находится в [Service] раздел, поэтому мое переопределение должно поместить ExecStart в [Service] раздел также. Часто, взглянув на фактический служебный файл с помощью systemctl cat подскажет вам, что вам нужно переопределить и в каком разделе это находится.

Обычно, если вы редактируете модульный файл systemd, чтобы он вступил в силу, вам необходимо запустить:

sudo systemctl daemon-reload

Однако, systemctl edit автоматически делает это за вас.

Сейчас:

$ systemctl cat getty@tty2 | grep ExecExecStart=-/sbin/agetty --noclear %I $TERMExecStart=ExecStart=-/sbin/agetty -a muru --noclear %I $TERM$ systemctl show getty@tty2 | grep ExecSExecStart={ path=/sbin/agetty ; argv[]=/sbin/agetty -a muru --noclear %I $TERM ; ... }

И если я это сделаю:

sudo systemctl restart getty@tty2

и нажмите CtrlAltF2, вуаля! Я войду в свою учетную запись на этом TTY.

Как я уже говорил раньше, getty@tty2 является экземпляром шаблона. Итак, что, если я захочу переопределить все экземпляры этого шаблона? Это можно сделать, отредактировав сам шаблон (удалив идентификатор экземпляра - в данном случае tty2):

systemctl edit getty@

Переопределение среды

Распространенный вариант использования /etc/default files - это настройка переменных окружения. Обычно, /etc/default это сценарий оболочки, поэтому вы можете использовать в нем конструкции языка оболочки. С systemd Однако это не так. Вы можете указать переменные среды двумя способами:

Через файл

Допустим, вы установили переменные среды в файле:

$ cat /path/to/some/fileFOO=bar

Затем вы можете добавить к переопределению:

[Service]EnvironmentFile=/path/to/some/file

В частности, если ваш /etc/default/grub содержит только назначения и не содержит синтаксиса оболочки, вы могли бы использовать его в качестве EnvironmentFile.

Через Environment записи

Вышеуказанное также может быть выполнено с помощью следующего переопределения:

[Service]Environment=FOO=bar

Однако это может быть сложно с несколькими переменными, пробелами и т.д. Взгляните на один из моих других ответов для примера такого экземпляра.

Вариации в редактировании

Полная замена существующего блока

Если вы хотите внести значительные изменения в существующее устройство, чтобы фактически полностью заменить его, вы могли бы просто сделать:

systemctl edit --full foo

Временные изменения

В файловой иерархии systemd, /run имеет приоритет над /etc, который , в свою очередь , имеет приоритет над /lib. Все сказанное до сих пор также относится к использованию /run/systemd/system вместо /etc/systemd/system. Обычно /run это временная файловая система, содержимое которой теряется при перезагрузке, поэтому, если вы хотите переопределить модуль только до перезагрузки, вы можете сделать:

systemctl edit --runtime foo

Отмена изменений

Вы можете просто удалить соответствующий файл переопределения и выполнить systemctl daemon-reload чтобы systemd прочитал обновленное определение единицы измерения.

Вы также можете возвращаться все изменения:

systemctl revert foo

Дальнейшее чтение

С помощью этого механизма становится очень легко переопределить systemd единиц измерения, а также для отмены таких изменений (простым удалением файла переопределения). Это не единственные настройки, которые можно изменить.

Следующие ссылки были бы полезны:

Обратите внимание, что при очистке ExecStart= с пустой записью вы не можете поместить комментарий после нее, например: ExecStart= # Пустая строка, чтобы очистить предыдущие записи. Это будет воспринято как еще одна запись ExecStart= и добавлено в список. PS. Я не мог добавить комментарий к ответу муру из-за моей низкой репутации.