Служба падает из-за локали
У службы нет переменных локали, которые есть в вашем сеансе. Программы, зависящие от локали, либо жалуются на неё, либо неверно работают с кириллицей — и в терминале эта проблема не воспроизводится.
Вероятные причины
По порядку: сверху то, что встречается чаще.
-
Локаль не задана в unit-файле
Служба не читает профиль. Переменные локали для неё пусты, и программа падает или переходит на язык по умолчанию.
-
Нужная локаль не создана в системе
Даже заданная переменная не поможет, если локаль не сгенерирована: программа сообщит, что не может её применить.
-
Ожидается локаль, а нужна кодировка вывода
Иногда проблема не в локали, а в том, что программа пишет в журнал в другой кодировке. Тогда в journalctl видны искажённые символы.
Диагностика
Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.
Общее окружение менеджера: там видно, задана ли локаль глобально.
systemctl show-environmentКакие локали созданы в системе.
locale -a | head -20Системная локаль по данным systemd.
localectl statusРешение
Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.
- Почему происходит
- Служба не читает профиль. Переменные локали для неё пусты, и программа падает или переходит на язык по умолчанию.
- Как проверить
-
Посмотрите окружение службы.
systemctl show myapp.service -p Environment systemctl show-environment | grep -i lang
- Как исправить
-
Задайте локаль явно в unit-файле.
[Service] Environment=LANG=ru_RU.UTF-8 Environment=LC_ALL=ru_RU.UTF-8
- Почему происходит
- Даже заданная переменная не поможет, если локаль не сгенерирована: программа сообщит, что не может её применить.
- Как проверить
-
Посмотрите доступные локали.
locale -a | grep -i ru locale 2>&1 | head
- Как исправить
-
Создайте локаль средствами дистрибутива и перезапустите службу.
sudo locale-gen ru_RU.UTF-8 && sudo update-locale
- Почему происходит
- Иногда проблема не в локали, а в том, что программа пишет в журнал в другой кодировке. Тогда в journalctl видны искажённые символы.
- Как проверить
-
Посмотрите вывод и настройки программы.
journalctl -u myapp.service -n 10 --no-pager | cat -v | head
- Как исправить
- Настройте программу на вывод в UTF-8: журнал systemd работает с ним.
Пример вывода
Программа не может применить локаль. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.
myapp[4500]: warning: setlocale: LC_ALL: cannot change locale (ru_RU.UTF-8): No such file or directory
myapp[4500]: fatal: cannot format report: invalid locale
Связанные ошибки
- Переменная в unit-файле не разворачивается Запись со знаком доллара попадает в аргументы буквально. Где подстановка работает, а где нет.
- В терминале работает, а под systemd нет Самая частая жалоба: программа запускается руками, но не как служба. Полный разбор отличий окружения.
- Node-служба не видит переменные окружения Приложение падает из-за отсутствующих переменных: файл .env не читается службой, окружение задаётся иначе.
- PostgreSQL: локаль кластера не совпадает с системой Кластер не запускается или сортировка ломается после обновления системы: несовпадение версии библиотеки локалей.
- Имена разрешаются не через ту подсистему Служба не находит узел, который виден другим средствам: порядок источников разрешения имён задан иначе.
- Контейнеры не запускаются: среда выполнения не найдена Служба контейнеров работает, а запуск контейнера отказывает: нет исполняемого файла среды выполнения в пути службы.
- Служба на Python не находит зависимости Модули не импортируются: в unit-файле указан системный интерпретатор вместо интерпретатора окружения.
- Служба синхронизации файлов работает не с тем каталогом Настройки и данные ищутся не там, где ожидалось: домашний каталог службы не тот, что у пользователя.
Источники
-
localectl(1)
Системная локаль и её настройка. -
systemd.exec(5)
Окружение службы и переменные локали. -
Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
Проверено на службе, форматирующей отчёт по локали.