Вики / Базовые команды
Локаль и кодировка (locale)
Язык, кодировка и форматы — LANG/LC_*, генерация локалей, проблемы с UTF-8.
Локаль задаёт язык, кодировку и форматы (даты, числа, сортировка) — через
переменные окружения $LANG/$LC_*. На серверах важна прежде всего
кодировка: для корректного UTF-8 нужна *.UTF-8 локаль.
locale # текущие настройки локали
locale -a # какие локали установлены
echo $LANG # основная переменная
sudo locale-gen en_US.UTF-8 ru_RU.UTF-8 # сгенерировать локали
sudo update-locale LANG=en_US.UTF-8 # системная локаль по умолчанию (/etc/default/locale)
# временно в текущей сессии:
export LANG=ru_RU.UTF-8
localectl status # системная локаль (systemd)
sudo localectl set-locale LANG=en_US.UTF-8
sudo dpkg-reconfigure locales # интерактивный выбор (Debian/Ubuntu)
Иерархия: LC_ALL (перебивает всё) > конкретные LC_* > LANG (общий дефолт).
| Переменная | На что влияет |
|---|---|
LANG |
общий дефолт для всех категорий |
LC_CTYPE |
кодировка (UTF-8!) |
LC_TIME |
формат даты/времени (см. date) |
LC_NUMERIC |
десятичный разделитель (. или ,) |
LC_COLLATE |
порядок сортировки (sort) |
LC_ALL |
перебивает всё (для скриптов: LC_ALL=C) |
Кракозябры вместо кириллицы/символов
Не UTF-8 локаль или терминал. Проверь locale (должно быть *.UTF-8), сгенерируй
(locale-gen), и что терминал/SSH в UTF-8.
warning: setlocale: LC_*: cannot change locale
Запрошенная локаль не сгенерирована. sudo locale-gen <локаль>; убедись, что она в
locale -a. Частое по SSH: клиент шлёт LC_* (через SendEnv), а на сервере её
нет — либо сгенерируй, либо убери приём (AcceptEnv в sshd).
Скрипт по-разному сортирует/парсит на разных машинах
Локаль влияет на sort, числа, даты. Для предсказуемости: export LC_ALL=C (байтовая
сортировка, точка как десятичный разделитель). Часто ставят в начале скриптов.
Дата/числа в «неожиданном» формате
LC_TIME/LC_NUMERIC. Зафиксируй нужную локаль или LC_ALL=C для машинного вывода.
Разово: LC_ALL=C sort file, LC_TIME=ru_RU.UTF-8 date.
perl: warning setting locale failed
Часто безвредно, но раздражает: на сервере нет локали, переданной по SSH. Лечится
генерацией нужной локали или AcceptEnv-фильтром.
locale ; locale -a # текущая / доступные
sudo locale-gen ru_RU.UTF-8 # сгенерировать
sudo update-locale LANG=en_US.UTF-8 # системная (или localectl set-locale)
export LC_ALL=C # стабильный вывод в скриптах
LC_ALL=C sort file # разовая байтовая сортировка
localectl status # systemd-вид
См. также
- Базовые команды с файлами — Базовые команды
- Переменные окружения и PATH — Базовые команды
- Время, часовой пояс и NTP — Службы и systemd