Unit has invalid ExecStart syntax — Ошибка синтаксиса команды запуска
Архитектура ошибки и симптомы сбоя
Синтаксическая ошибка «Unit app.service has invalid ExecStart= syntax (or path is not absolute)» генерируется диспетчером systemd при попытке загрузить или запустить юнит. Диспетчер systemd не использует стандартную командную оболочку (sh/bash) для вызова ExecStart=. Ошибка указывает на нарушение правил парсинга: указан относительный путь к исполняемому файлу вместо абсолютного, используются неэкранированные пайпы (|), редиректы (>, <), подстановки переменных или множественные команды без вызова shell.
Диагностическая таблица параметров сбоя
| Параметр | Значение | Инженерный смысл сбоя |
|---|---|---|
| Absolute Path Requirement | Must start with / | Бинарный файл должен начинаться строго с абсолютного пути (например, /usr/bin/node). |
| Shell Metacharacters | |, &, ;, >, <, * | Символы перенаправления потоков не поддерживаются синтаксисом systemd напрямую. |
| Prefix Modifiers | -, @, +, ! | Специальные префиксы systemd (игнорирование ошибок, сброс привилегий, запуск от root). |
Пошаговое дерево решений и сценарии траблшутинга
Сценарий 1: Исправление относительного пути на абсолютный
Найдите точный путь к бинарному файлу с помощью утилиты which или whereis:
# Поиск абсолютного пути к утилите:
which python3
which npm
# НЕПРАВИЛЬНО в unit-файле:
# ExecStart=python3 app.py
# ПРАВИЛЬНО:
# ExecStart=/usr/bin/python3 /opt/app/app.pyСценарий 2: Корректное использование пайпов и редиректов через bash -c
Если команде требуются конвейеры (|), перенаправления в файл (>>) или сложные логические цепочки (&&):
# Оберните команду в явный вызов командного интерпретатора:
[Service]
ExecStart=/bin/bash -c '/usr/bin/app_binary | /usr/bin/tee -a /var/log/app.log 2>&1'Сценарий 3: Передача переменных окружения и аргументов
Используйте синтаксис ${VAR} и обязательно задайте директиву Environment=:
[Service]
Environment="PORT=8080" "ENV=production"
ExecStart=/usr/bin/app_server --port=${PORT} --mode=${ENV}Сценарий 4: Проверка валидности и перезапуск юнита
# Проверка синтаксиса юнита утилитой systemd-analyze:
systemd-analyze verify app.service
# Применение исправлений:
sudo systemctl daemon-reload
sudo systemctl restart app.serviceITSTM переработает конфигурации systemd, настроит безопасную передачу секретов и стандартизирует runtime окружение.
Частые вопросы (FAQ)
Что означает префикс '-' перед путем в ExecStart=-/path/to/bin?
Префикс '-' указывает systemd игнорировать ненулевой код возврата этой команды и не считать службу завершившейся аварийно.
Что означает префикс '+' или '!' перед командой ExecStart?
Префикс '+' запускает команду с полными правами root (вне песочницы сервиса). Префикс '!' запускает команду с повышенными правами, даже если для сервиса задан непривилегированный User=.
Можно ли указывать несколько строк ExecStart= в одном сервисе?
Для стандартных сервисов (Type=simple/forking) допускается только одна строка ExecStart=. Несколько ExecStart= разрешены исключительно для сервисов с типом Type=oneshot.
Как очистить ранее заданный ExecStart при переопределении через drop-in файл?
В секции [Service] укажите сначала пустую директиву 'ExecStart=', а затем новую команду 'ExecStart=/new/bin/path'.