Вопрос или проблема
Я создал файл systemd для моего bash-скрипта на .NET Core в Linux. Но когда я запускаю файл службы, systemd
постоянно завершает его с результатом “служба: успешно деактивирована.”
Я пытался вставить Type=forking
или Type=oneshot
, но ни один из вариантов не сработал. Что мне делать?
Вот файл службы:
[Unit]
Description=Пример приложения .NET Web API, работающего на Ubuntu
[Service]
Type=oneshot
ExecStart=/usr/bin/updatem
User=root
[Install]
WantedBy=multi-user.target
Вот результат:
10:57 AM kill UpdateM
10:57 AM запуск UpdateM
10:57 AM 3
10:57 AM 2
10:57 AM 1
10:57 AM UpdateM (v.1.0.0.12)
10:57 AM UpdateM (v.1.0.0.12) запущен.
10:57 AM Запуск
10:57 AM updatem.service: успешно деактивирована.
10:57 AM Завершено. Пример приложения .NET Web API, работающего на Ubuntu.
С Type=oneshot
вам часто также потребуется RemainAfterExit=yes
, чтобы systemd считал службу “работающей” после завершения процесса, вызванного строкой ExecStart=
.
Из man systemd.service
о Type=oneshot
:
Обратите внимание, что если этот параметр используется без
RemainAfterExit=
, служба никогда не войдет в состояние “активного” юнита, а сразу перейдет из состояния “активации” в “деактивацию” или “мертва”, так как не настроен процесс, который должен работать непрерывно. В частности, это означает, что после выполнения службы такого типа (и которая не имеет установленногоRemainAfterExit=
) она не будет показана как запущенная впоследствии, а как мертвая.
Таким образом, поведение, которое вы наблюдаете, именно то, что ожидается с Type=oneshot
+ без RemainAfterExit=yes
.
Если ваш скрипт /usr/bin/updatem
фактически создает дочерний процесс, который должен продолжать работу, то Type=forking
будет правильным выбором типа службы.
Но если скрипт /usr/bin/updatem
просто отправляет команду другому уже существующему процессу, вызывая его для запуска чего-то еще, и скрипт вместе со всеми его прямыми потомками завершится, как только команда будет отправлена, то Type=oneshot
, вероятно, с RemainAfterExit=yes
, будет правильным выбором.
Вы также можете добавить строку ExecStop=
, указывающую на другой скрипт, который отправит другую команду для остановки процесса, запущенного скриптом /usr/bin/updatem
, если это необходимо. Это позволит systemctl stop UpdateM.service
также быть значимой операцией и сделает так, что systemd остановит ваш процесс более корректно во время завершения работы системы, если он все еще работает.
Если вы измените файл службы без использования systemctl edit
, не забудьте запустить systemctl daemon-reload
, чтобы изменения в файле службы вступили в силу.
Ответ или решение
Конечно! Вот полный ответ на ваш вопрос относительно того, почему ваш сервис с .NET (в данном случае, скрипт updatem
) завершает свою работу с сообщением "Deactivated successfully" и что можно сделать, чтобы это исправить.
Проблема
Вы наблюдаете следующую ситуацию: когда вы запускаете свой сервис, он завершает выполнение моментально, и systemd
сообщает, что сервис "успешно деактивирован". Это поведение ожидаемо для сервиса, определенного с типом Type=oneshot
, так как он сразу же завершает свою работу после выполнения команды.
Решение
Вам нужно выбрать правильный тип сервиса и возможно добавить некоторые дополнительные параметры, чтобы управлять поведением вашего скрипта.
-
Тип сервиса:
- Если ваш скрипт
updatem
создает дочерний процесс, который должен продолжать работать, вам следует использоватьType=forking
. Это позволяетsystemd
отслеживать родительский процесс, который вы создали, и считать сервис работающим до тех пор, пока процесс не завершится. - Если ваш скрипт просто инициирует другую задачу (например, отправляет команду на старт другого приложения) и сам по себе завершается, то вам следует использовать
Type=oneshot
, но с добавлением параметраRemainAfterExit=yes
.
- Если ваш скрипт
-
Пример конфигурации сервиса:
Вот как может выглядеть ваша служебная конфигурация для обоих случаев:
Вариант 1: Use Type=forking
[Unit]
Description=Example .NET Web API App running on Ubuntu
[Service]
Type=forking
ExecStart=/usr/bin/updatem
User=root
[Install]
WantedBy=multi-user.target
Вариант 2: Use Type=oneshot
with RemainAfterExit=yes
[Unit]
Description=Example .NET Web API App running on Ubuntu
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/updatem
User=root
[Install]
WantedBy=multi-user.target
Дополнительные настройки
- ExecStop: Вы также можете добавить строку
ExecStop=
, которая укажет команду для остановки сервиса, если это необходимо. Это позволит вашему сервису быть корректно остановленным черезsystemctl stop UpdateM.service
.
Перезагрузка конфигурации
После внесения изменений в файл сервиса не забудьте выполнить команду systemctl daemon-reload
, чтобы применить изменения в конфигурации.
Заключение
С учетом вышеизложенного, правильный выбор типа сервиса и использование параметра RemainAfterExit=yes
помогут вам успешно управлять вашим сервисом и избежать нежелательной деактивации. Проверяйте логи journalctl -u UpdateM.service
для получения дополнительной информации о состоянии вашего сервиса в случае возникновения проблем.