Вопрос или проблема
Я часто устанавливаю Debian. Для этого у меня есть полностью автоматизированный preseed.cfg; в конце preseed он загружает и запускает сценарий postinstall.sh с моего TFTP-сервера, который делает некоторую дополнительную настройку.
Я в процессе перехода с GNOME на LXQTE и использую SDDM вместо GDM. Однако SDDM пытается запуститься слишком быстро для моего оборудования. Чтобы обойти это, я использовал systemctl edit sddm
, чтобы добавить следующее:
[Service]
ExecStartPre=/bin/sleep 5
Это отлично работает, и я хотел бы автоматизировать этот процесс, добавив его в сценарий postinstall.sh. Однако я не могу понять, как передать содержимое файла в systemctl edit
через bash-скрипт. Как я могу это сделать?
Вы можете переопределить $SYSTEMD_EDITOR
переменную окружения, чтобы использовать другую команду вместо вашего редактора при запуске systemctl edit
.
Например, использование чего-то вроде SYSTEMD_EDITOR='cp /path/to/source.file'
похоже работает нормально (хотя это довольно уродливо, ожидая, что последний аргумент будет добавлен systemd!)
Для вашего конкретного случая, вы могли бы использовать:
$ { echo "[Service]";
echo "ExecStartPre=/bin/sleep 5";
} >~/tmp/sddm-override.conf
$ sudo env SYSTEMD_EDITOR="cp $HOME/tmp/sddm-override.conf" systemctl edit sddm
Но все, что systemctl edit
действительно делает — это создает файл переопределения (в его случае, названный override.conf
) в каталоге /etc/systemd/system/<service>.service.d/
, который создается, если не существует… Поэтому выполнение этого напрямую также является totalmente допустимым подходом. (См. упоминания о “drop-in” и “override” в man-странице systemd.unit для более подробной информации.)
Таким образом, в вашем случае, это было бы подходящее решение:
$ sudo mkdir -p /etc/systemd/system/sddm.service.d/
$ { echo "[Service]";
echo "ExecStartPre=/bin/sleep 5";
} | sudo tee /etc/systemd/system/sddm.service.d/10-startup-delay.conf
$ sudo systemctl daemon-reload
Который помещает файл с ожидаемым содержимым в “drop-in” каталог для вашего юнита, в этом случае вы также можете назвать его соответственно тому, что он пытается выполнить.
ОБНОВЛЕНО: Как указывает @GracefulRestart, после добавления “drop-in” требуется systemctl daemon-reload
.
Поскольку я пока не нашел, как использовать systemctl edit
в скрипте, лучшей практикой было бы имитировать команду systemctl edit sddm
и поместить переопределение в директорию /etc/systemd/system, так как юниты сервисов в /usr/lib/systemd/system могут быть изменены при обновлении пакетов:
UNIT='sddm.service'
DIR="/etc/systemd/system/${UNIT}.d"
mkdir $DIR
echo -e "[Service]\nExecStartPre=/bin/sleep 5" > ${DIR}/override.conf
systemctl daemon-reload
Это должно быть примерно эквивалентно тому, что делает systemctl edit sddm
.
Вы можете изменить, какой редактор systemctl(8)
использует для своей подкоманды edit
с помощью переменной SYSTEMD_EDITOR
. Это по существу конструирует команду, последний аргумент которой всегда является временным файлом, созданным systemctl(8)
, который после записи перемещается в override.conf
.
Из-за этого мы можем использовать tee(1)
в качестве SYSTEMD_EDITOR
и затем перенаправить любой текст, который мы хотим, всей команде systemctl(8)
через стандартный ввод. Например, перенаправив Here-Document:
SYSTEMD_EDITOR=tee systemctl edit sddm <<EOF
[Service]
ExecStartPre=/bin/sleep 5
EOF
Это создаст файл с “drop-in” /etc/systemd/system/sddm.service.d/override.conf
с содержимым между “словами” EOF
.
Под капотом команда edit
выполняет что-то вроде этого:
# Создать каталог drop-in для сервиса
mkdir -p /etc/systemd/system/sddm.service.d
# Создать пустой временный файл
touch /etc/systemd/system/sddm.service.d/.
# Передать временный файл в качестве последнего аргумента SYSTEMD_EDITOR
tee /etc/systemd/system/sddm.service.d/.\#override.conf846580011dbe64db/.\#override.conf846580011dbe64db<<EOF
[Service]
ExecStartPre=/bin/sleep 5
EOF
# Переименовать временный файл
mv /etc/systemd/system/sddm.service.d/{.\#override.conf846580011dbe64db,override.conf}
После редактирования юнита конфигурация systemd автоматически перезагружается (аналогично команде daemon-reload
).
Я хочу дополнить ответ, данный в 3, но я делаю это следующим образом, используя tee
env SYSTEMD_EDITOR=tee sudo -E systemctl edit --system [your_unit_name] < [your_content_file]
При таком подходе вы можете передавать содержимое через stdin, а не из файла, что может быть полезно при вызове systemctl из скрипта.
systemd v256 (июнь 2024) получил поддержку для неинтерактивного редактирования с помощью новой опции --stdin
:
* 'systemctl edit --stdin' позволяет создавать файлы юнитов и "drop-in" файлы с содержимым, переданным через стандартный ввод. Это полезно при программном создании конфигурации; инструмент заботится о нахождении имени файла, создании директорий и перезагрузке менеджера после этого.
Используйте это таким образом, чтобы создать “drop-in” файл для сервиса sddm
:
systemctl edit --stdin sddm <<EOF
[Service]
ExecStartPre=/bin/sleep 5
EOF
Это создаст /etc/systemd/system/sddm.service.d/override.conf
.
Если указано --drop-in=
, будет использовано данное имя файла вместо стандартного override.conf
. Пример:
systemctl edit --drop-in=my-drop-in.conf --stdin sddm <<EOF
[Service]
ExecStartPre=/bin/sleep 5
EOF
Я бы напрямую изменил файл:
sed -i 's/\[Service]/ a\
ExecStartPre=/bin/sleep 5' /usr/lib/systemd/system/sddm.service
Ответ или решение
Как автоматизировать изменение конфигурации службы SDDM на Debian через bash-скрипт
Вы часто устанавливаете Debian, и в процессе перехода с GNOME на LXQt возникла необходимость использовать SDDM вместо GDM. Однако служба SDDM запускается слишком быстро для вашего оборудования, и вы хотите добавить задержку перед её запуском. Обычно вы используете systemctl edit sddm
для добавления строки ExecStartPre=/bin/sleep 5
в файл override.conf. Теперь вы хотите автоматизировать этот процесс, добавив его в ваш сценарий postinstall.sh.
Шаги для автоматизации через bash-скрипт
Подготовка окружения
- Создайте временный файл конфигурации: Используйте механизм создания временных файлов для подготовки содержимого нового конфигурационного файла.
Автоматическая правка файла конфигурации
Вы можете напрямую создать "дроп-ин" файл для службы SDDM, используя следующий подход:
# Создайте директорию для дроп-ин файлов, если она не существует
sudo mkdir -p /etc/systemd/system/sddm.service.d/
# Создайте временный дроп-ин файл и добавьте задержку перед запуском
echo "[Service]
ExecStartPre=/bin/sleep 5" | sudo tee /etc/systemd/system/sddm.service.d/10-startup-delay.conf > /dev/null
# Перезагрузите конфигурации systemd для применения изменений
sudo systemctl daemon-reload
Дополнительные методы
-
Использование tee и SYSTEMD_EDITOR:
- Вы можете настроить переменную окружения
SYSTEMD_EDITOR
для выполнения командыtee
, что позволит передавать содержимое через стандартный ввод:SYSTEMD_EDITOR=tee sudo systemctl edit sddm <<EOF [Service] ExecStartPre=/bin/sleep 5 EOF
Это создаст файл
/etc/systemd/system/sddm.service.d/override.conf
.
- Вы можете настроить переменную окружения
-
Редактирование через stdin с systemctl: В будущих версиях systemd (начиная с v256) появится поддержка для
--stdin
-параметра, который позволит использовать стандартный ввод:systemctl edit --stdin sddm <<EOF [Service] ExecStartPre=/bin/sleep 5 EOF
Этот подход будет автоматически выполнять все необходимые действия по созданию файлов и перезагрузке конфигурации.
Заключение
Ваша задача создать автоматизированный метод для модификации конфигурации службы SDDM на Debian. Прямое создание дроп-ин файлов является надежным и профессиональным решением, которое упрощает взаимодействие с systemd и позволяет избежать человеческих ошибок. Такой подход структурирует управление системными службами в вашем скрипте postinstall.sh, обеспечивая эффективную автоматизацию без вмешательства в базовые файлы конфигурации.
Оптимизация текстового содержания и непосредственное воздействие на файлы конфигурации способствуют профессиональному обслуживанию системы, и могут быть легко интегрированы в существующие автоматизированные процессы.