Вопрос или проблема
Я пытаюсь написать файл unit для systemd. Когда я запускаю службу siad, я хочу запустить другую команду, /usr/sbin/clearshare-scheduler.sh, которая может выполняться в течение нескольких часов или завершиться немедленно. Я пробовал сделать это с помощью ExecStartPost, но systemd не одобряет, если команда не завершится в короткий срок и выдает сообщение об ошибке. Пример файла:
[Unit]
Description=Siad
After=syslog.target network.target
[Service]
Type=simple
OOMScoreAdjust=500
PIDFile=/var/run/siad.pid
EnvironmentFile=/etc/sysconfig/siad
Environment="SIA_DATA_DIR=/var/lib/siad-data"
ExecStart=/usr/bin/siad $EXTRA_ARGS
ExecStop=/usr/bin/siac stop
WorkingDirectory=/var/lib/sia/
ExecStartPost=/usr/bin/sh -c 'umask 022; /usr/bin/pgrep siad > /var/run/siad.pid'
ExecStartPost=/usr/sbin/clearshare-scheduler.sh
[Install]
WantedBy=multi-user.target
Я пробовал запускать его с помощью “&”, чтобы поместить в фоновый режим, и с помощью nohup, но это тоже не сработало.
Попробуйте добавить TimeoutStartSec=
под [Service]
. Это влияет на все процедуры запуска.
https://www.freedesktop.org/software/systemd/man/systemd.service.html#TimeoutStartSec=
Просто добавьте команду /usr/sbin/clearshare-scheduler.sh
как вторую службу, так как она требует от вашей первой службы. Надеюсь, это поможет!
Ответ или решение
Для того чтобы корректно запускать команду clearshare-scheduler.sh
в файле единицы systemd, которая может выполняться долго или завершаться сразу, необходимо учитывать несколько важных аспектов. Ваша текущая реализация с использованием ExecStartPost
может привести к неудачам, если выполняемая команда не завершится в течение заданного времени. В этом ответе я предложу подход, который позволит избежать этих проблем.
Решение проблемы
Подход 1: Использование ExecStart
с фоновым запуском
Одним из решений данной проблемы является запуск вашей команды с помощью ExecStart
, добавляя к ней &
для выполнения в фоновом режиме. Однако учтите, что для повышения устойчивости и контроля над процессом, можно обернуть команду в скрипт.
-
Создание вспомогательного скрипта:
Создайте скрипт, который будет запускать вашу команду в фоне и завершать выполнение, не дожидаясь её завершения. Например, создайте файл
/usr/local/bin/start-clearshare-scheduler.sh
с содержимым:#!/bin/bash /usr/sbin/clearshare-scheduler.sh &
Не забудьте сделать его исполняемым:
chmod +x /usr/local/bin/start-clearshare-scheduler.sh
-
Обновление файла единицы systemd:
Теперь вы можете изменить ваш unit-файл следующим образом:
[Unit] Description=Siad After=syslog.target network.target [Service] Type=simple OOMScoreAdjust=500 PIDFile=/var/run/siad.pid EnvironmentFile=/etc/sysconfig/siad Environment="SIA_DATA_DIR=/var/lib/siad-data" ExecStart=/usr/bin/siad $EXTRA_ARGS ExecStop=/usr/bin/siac stop WorkingDirectory=/var/lib/sia/ ExecStartPost=/usr/bin/sh -c 'umask 022; /usr/bin/pgrep siad > /var/run/siad.pid' ExecStartPost=/usr/local/bin/start-clearshare-scheduler.sh [Install] WantedBy=multi-user.target
Подход 2: Создание отдельной службы для clearshare-scheduler.sh
Если clearshare-scheduler.sh
имеет свои зависимости и его стоит отслеживать отдельно, вы можете создать для него отдельный unit-файл:
-
Создание нового unit-файла:
Создайте файл, например,
/etc/systemd/system/clearshare-scheduler.service
:[Unit] Description=Clearshare Scheduler After=siad.service [Service] Type=simple ExecStart=/usr/sbin/clearshare-scheduler.sh [Install] WantedBy=multi-user.target
-
Обновление основного unit-файла:
Теперь просто измените ваш первоначальный unit-файл, убрав команду для
clearshare-scheduler.sh
:[Unit] Description=Siad After=syslog.target network.target [Service] Type=simple OOMScoreAdjust=500 PIDFile=/var/run/siad.pid EnvironmentFile=/etc/sysconfig/siad Environment="SIA_DATA_DIR=/var/lib/siad-data" ExecStart=/usr/bin/siad $EXTRA_ARGS ExecStop=/usr/bin/siac stop WorkingDirectory=/var/lib/sia/ ExecStartPost=/usr/bin/sh -c 'umask 022; /usr/bin/pgrep siad > /var/run/siad.pid' [Install] WantedBy=multi-user.target
-
Запуск и активация службы:
Чтобы активировать и запустить новую службу, выполните следующие команды:
systemctl daemon-reload systemctl enable clearshare-scheduler.service
Заключение
Оба предложения обеспечивают то, что команда clearshare-scheduler.sh
может выполняться долго, не вызывая сбоев в вашем основном сервисе siad
. Выбор между первым и вторым подходом зависит от вашей архитектуры. Первый подойдет для простоты, второй — для большей модульности и отслеживания состояния.