ExecStart= в systemd: правила записи команды запуска
Задаёт программу, которую systemd запускает при старте службы, вместе с аргументами. Путь обязательно абсолютный: поиска в PATH здесь нет.
Что делает
Строка разбирается самим systemd, а не оболочкой. Это главное, что нужно помнить: конвейеры, перенаправления, подстановки и звёздочки в именах файлов не работают — они попадают программе как обычные аргументы. Если нужна оболочка, её вызывают явно: ExecStart=/bin/sh -c '...'.
Перед путём допустимы префиксы. Дефис делает неудачу команды несущественной, @ меняет нулевой аргумент, + снимает ограничения изоляции для этой команды, ! запускает её с правами до смены пользователя. Их можно сочетать.
Где ставится. В секции [Service]. Обязателен для всех типов, кроме oneshot, где допустимо его отсутствие или несколько строк.
Значения
| Значение | Что происходит |
|---|---|
/usr/bin/prog arg1 arg2 | обычный вид: абсолютный путь и аргументы через пробел. |
-/usr/bin/prog | дефис: ненулевой код возврата не считается ошибкой службы. |
@/usr/bin/prog myname | первый аргумент после пути становится нулевым аргументом процесса. |
+/usr/bin/prog | команда выполняется без ограничений изоляции и с полными правами. |
!/usr/bin/prog | команда выполняется до смены пользователя, с правами менеджера. |
Пример
Прямой запуск и запуск через оболочку, когда нужен конвейер.
[Service]
ExecStart=/usr/local/bin/myapp --config /etc/myapp.yml --workers 4
# перенаправление требует оболочки: systemd её не даёт
ExecStart=/bin/sh -c '/usr/local/bin/report | /usr/bin/gzip > /var/lib/report.gz'
Во втором случае в журнале и в статусе будет виден /bin/sh, а не ваша программа. Поэтому оболочку стоит вызывать только когда она действительно нужна.
Типичные ошибки
Относительный путь или имя команды без пути дают код 203/EXEC: systemd не ищет программу в PATH.
Символы |, >, &&, $( попадают в аргументы буквально. Программа получает не то, что вы задумали, а результат зависит от неё.
Несколько ExecStart= допустимы только при Type=oneshot. В остальных типах это отказ загрузки unit.
В переопределении через drop-in нужно сначала сбросить значение пустой строкой ExecStart=, иначе получится две команды.
Связанные ошибки
- status=203/EXEC в systemdКод 203/EXEC означает, что systemd не смог выполнить программу из ExecStart=. Разбор причин: путь, права, интерпретатор, синтаксис оболочки.
- status=127 в systemd: команда не найденаКод 127 без имени: оболочка не нашла команду. Появляется, когда ExecStart запускает скрипт или sh -c, а внутри команды нет.
- Переопределение через drop-in не применяетсяПравка через systemctl edit или файл в каталоге .d не действует: разбор причин, включая особенность списочных параметров и ExecStart.
- status=2/INVALIDARGUMENT в systemdКод 2/INVALIDARGUMENT: программа сочла аргументы или настройки недопустимыми. Частая причина — лишние кавычки в ExecStart=.
Рядом стоящие параметры
Где важен на практике
Источники
- systemd.service(5)
- Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)