SystemdDoctor
служба не работает конфигурация execstart

Кавычки в ExecStart= разбираются не так, как ожидается

systemd разбирает строку запуска по своим правилам: кавычки снимаются, пробелы делят аргументы. Запись, скопированная из терминала, часто даёт программе не те аргументы — и она либо падает, либо работает не так.

Что это значит

Проверять надо не файл, а результат разбора: systemctl show -p ExecStart печатает аргументы по отдельности. Если аргумент разъехался на два или содержит лишние кавычки, это видно сразу.

Вероятные причины

По порядку: сверху то, что встречается чаще.

  1. Кавычки вокруг всего значения параметра

    Запись ExecStart="/usr/bin/app --opt a b" даёт один аргумент — путь с пробелами внутри. Программа не запустится.

  2. Одинарные кавычки внутри двойных или наоборот

    Правила systemd отличаются от правил оболочки. Вложенные кавычки разбираются иначе, чем ожидает человек.

  3. Обратная косая для переноса строки не там, где нужно

    Перенос допустим, но обратная косая должна быть последним символом строки. Пробел после неё ломает разбор.

Диагностика

Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.

Разобранная команда: аргументы видны по отдельности.

systemctl show myapp.service -p ExecStart

Ошибки разбора строки запуска.

systemd-analyze verify /etc/systemd/system/myapp.service

Что сказала программа о полученных аргументах.

journalctl -u myapp.service -n 20 --no-pager

Решение

Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.

1. Кавычки вокруг всего значения параметра
Почему происходит
Запись ExecStart="/usr/bin/app --opt a b" даёт один аргумент — путь с пробелами внутри. Программа не запустится.
Как проверить
Посмотрите разобранные аргументы.
systemctl show myapp.service -p ExecStart
Как исправить
Кавычки нужны только вокруг отдельных аргументов с пробелами, а не вокруг всей команды.
ExecStart=/usr/bin/app --opt "a b"
2. Одинарные кавычки внутри двойных или наоборот
Почему происходит
Правила systemd отличаются от правил оболочки. Вложенные кавычки разбираются иначе, чем ожидает человек.
Как проверить
Сравните написанное и разобранное.
systemctl cat myapp.service | grep ExecStart
systemctl show myapp.service -p ExecStart
Как исправить
Избегайте вложенных кавычек: если аргумент сложный, вынесите его в файл окружения или в скрипт.
3. Обратная косая для переноса строки не там, где нужно
Почему происходит
Перенос допустим, но обратная косая должна быть последним символом строки. Пробел после неё ломает разбор.
Как проверить
Посмотрите невидимые символы в конце строк.
grep -n "\\\\ *$" /etc/systemd/system/myapp.service | cat -A | head
Как исправить
Уберите пробелы после обратной косой. Проверка unit-файла на этом сайте такие строки отмечает.

Пример вывода

Кавычки вокруг всей команды. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.

$ systemctl cat myapp.service | grep ExecStart
ExecStart="/usr/local/bin/myapp --listen 127.0.0.1:8080"

$ systemctl show myapp.service -p ExecStart
ExecStart={ path=/usr/local/bin/myapp --listen 127.0.0.1:8080 ; argv[]=... }

systemd[4100]: myapp.service: Failed at step EXEC spawning /usr/local/bin/myapp --listen 127.0.0.1:8080: No such file or directory

Связанные ошибки

Источники

  • systemd.service(5)
    Правила разбора командной строки и кавычек.
    официальная документация, systemd 255
    сверено 15 сентября 2026
  • Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
    Воспроизведено кавычками вокруг всей команды запуска.
    собственная проверка, systemd 255
    сверено 15 сентября 2026