Как установить локаль в безинтерактивном режиме на Debian/Ubuntu?

Вопрос или проблема

Обычно я запускаю aptitude -y install locales, а затем dpkg-reconfigure locales, чтобы настроить локаль.

Теперь я хочу поместить это в shell-скрипт, как я могу надежно сделать следующее автоматически / не интерактивно?

  • Выбрать en_US.UTF-8 и установить его в качестве системного по умолчанию
  • Отключить все другие локали
  • (Дополнительно) Проверить, содержит ли /etc/default/locale единственную запись LANG=en_US.UTF-8 как ожидалось

См. man 8 locale-gen:

Для автоматической настройки локали:

sed -i 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/g' /etc/locale.gen
echo 'LANG=en_US.UTF-8' > /etc/default/locale
locale-gen

Не удалось заставить @stone’s answer работать. Вместо этого я использую этот метод (для Dockerfiles):

# Настройка часового пояса и локали
echo "Europe/Oslo" > /etc/timezone && \
    dpkg-reconfigure -f noninteractive tzdata && \
    sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
    sed -i -e 's/# nb_NO.UTF-8 UTF-8/nb_NO.UTF-8 UTF-8/' /etc/locale.gen && \
    echo 'LANG="nb_NO.UTF-8"'>/etc/default/locale && \
    dpkg-reconfigure --frontend=noninteractive locales && \
    update-locale LANG=nb_NO.UTF-8

Основываясь на отличной работе в ответе @EirikW. Специфично для Dockerfile:

ENV LANG=en_GB.UTF-8
RUN apt-get install -y locales && \
    sed -i -e "s/# $LANG.*/$LANG UTF-8/" /etc/locale.gen && \
    dpkg-reconfigure --frontend=noninteractive locales && \
    update-locale LANG=$LANG

Для меня было необходимо установить еще 3 переменные окружения:

# - Установка локали + часового пояса --------------------------------------------------
RUN echo "Europe/Vienna" > /etc/timezone && \
    dpkg-reconfigure -f noninteractive tzdata && \
    sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
    sed -i -e 's/# de_AT.UTF-8 UTF-8/de_AT.UTF-8 UTF-8/' /etc/locale.gen && \
    echo 'LANG="de_AT.UTF-8"'>/etc/default/locale && \
    dpkg-reconfigure --frontend=noninteractive locales && \
    update-locale LANG=de_AT.UTF-8

ENV LANG de_AT.UTF-8
ENV LANGUAGE de_AT.UTF-8
ENV LC_ALL de_AT.UTF-8

Однако спасибо ErikWs за его ответ: (https://serverfault.com/a/689947)

Чтобы перенастроить часовой пояс и локали не интерактивно, изнутри скрипта, вот что работает для меня (под управлением Debian):

  • Для настройки часового пояса я сначала создаю ‘/etc/localtime’ как символическую ссылку на соответствующий файл zoneinfo в каталоге ‘/usr/share/zoneinfo’. Затем я выполняю команду dpkg-reconfigure, и все будет на месте.
    Итак, например, чтобы установить часовой пояс ‘Europe/Brussels’:

    AREA='Europe'
    ZONE='Brussels'
    
    ZONEINFO_FILE='/usr/share/zoneinfo/'"${AREA}""https://serverfault.com/""${ZONE}"
    ln --force --symbolic "${ZONEINFO_FILE}" '/etc/localtime'
    dpkg-reconfigure --frontend=noninteractive tzdata
    

    (Обратите внимание, что AREA – это подсистема каталога ‘/usr/share/info’, а ZONE – это файл в подсистеме AREA).

  • Для настройки локалей я сначала запускаю скрипт sed, который создаст новую копию файла ‘/etc/locale.gen’, основываясь на содержимом файла ‘/usr/share/i18n/SUPPORTED’. Каждая строка из входного файла будет скопирована, но она будет превращена в комментарий, если это не запись UTF-8 локали для языка, который я хочу сделать доступным в моей системе (например, английский, нидерландский, французский и немецкий):

    sed --regexp-extended --expression='
    
       1  {
             i\
    # Этот файл перечисляет локали, которые вы хотите создать. Вы можете найти список\
    # действительных поддерживаемых локалей в /usr/share/i18n/SUPPORTED, и вы можете добавить\
    # определяемые пользователем локали в /usr/local/share/i18n/SUPPORTED. Если вы измените\
    # этот файл, вам нужно снова запустить locale-gen.\
    \
    
    
          }
    
       /^(en|nl|fr|de)(_[[:upper:]]+)?(\.UTF-8)?(@[^[:space:]]+)?[[:space:]]+UTF-8$/!   s/^/# /
    
    ' /usr/share/i18n/SUPPORTED >  /etc/locale.gen
    

    Далее я устанавливаю локаль по умолчанию в базе данных debconf, например, на британский английский:

    debconf-set-selections <<< 'locales locales/default_environment_locale select en_GB.UTF-8'
    

    Затем я удаляю существующий файл ‘/etc/default/locale’ (только чтобы убедиться, что его старое содержимое не помешает моим новым настройкам) и запускаю команду dpkg-reconfigure, чтобы сгенерировать все локали, которые выбрал скрипт sed, и создать новый файл ‘/etc/default/locale’ только с записью для установки переменной ‘LANG’ на мою выбранную локаль по умолчанию:

    rm --force --verbose /etc/default/locale
    dpkg-reconfigure --frontend=noninteractive locales
    

    Затем, в зависимости от моих требований, я могу запустить несколько команд update-locale, чтобы переопределить, например, переменные, которые влияют на форматирование значений, и установить их на другую локаль (такую как ирландский английский):

    update-locale LC_NUMERIC='en_IE.UTF-8'
    update-locale LC_TIME='en_IE.UTF-8'
    update-locale LC_MONETARY='en_IE.UTF-8'
    update-locale LC_PAPER='en_IE.UTF-8'
    update-locale LC_NAME='en_IE.UTF-8'
    update-locale LC_ADDRESS='en_IE.UTF-8'
    update-locale LC_TELEPHONE='en_IE.UTF-8'
    update-locale LC_MEASUREMENT='en_IE.UTF-8'
    update-locale LC_IDENTIFICATION='en_IE.UTF-8'
    

    (Я мог бы указать все эти параметры в одном вызове команды update-locale, но, похоже, порядок, в котором записи записываются в файл ‘/etc/default/locale’, непредсказуем, если я так делаю. Мне предпочтительнее, чтобы они всегда были в одном и том же порядке, поэтому я генерирую их по одной.)

    И, наконец, я могу запустить команду update-locale в последний раз, чтобы настроить переменную LANGUAGE (т.е. список языков, на которых я хочу, чтобы переводимые текстовые сообщения отображались):

    update-locale LANGUAGE='en_GB:en_US:en'
    

Соберите все это в bash-скрипт, и вы сможете легко перенастроить ваши настройки локали простым запуском скрипта, который не потребует дальнейшего взаимодействия с пользователем.

Однако, по моему опыту, новые настройки не активируются полностью до тех пор, пока вы не перезагрузите систему дважды (по крайней мере, на Debian Jessie Xfce). После первой перезагрузки менеджер входа примет новые настройки, но после входа в систему ваша пользовательская сессия продолжит использовать старые настройки; затем, после второй перезагрузки, ваша пользовательская сессия также примет новые настройки.

Вы можете выполнить 2 НПРЯМО, чтобы установить en_US.UTF-8 локали.

  1. Используйте cat или vim, чтобы увидеть временный конфигурационный файл:
sudo EDITOR='cat' dpkg-reconfigure -f editor locales
sudo EDITOR='vim' dpkg-reconfigure -f editor locales
  1. Используйте sed, чтобы заменить конфигурационный файл автоматически:
sudo EDITOR='sed -Ei "
    s|locales/locales_to_be_generated=.+|locales/locales_to_be_generated=\"en_US.UTF-8 UTF-8\"|; 
    s|locales/default_environment_locale=.+|locales/default_environment_locale=\"en_US.UTF-8\"|
    "' dpkg-reconfigure -f editor locales
sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
dpkg-reconfigure --frontend=noninteractive locales && \
update-locale LANG=en_US.UTF-8 LANGUAGE=en_US.UTF-8 LC_ALL=en_US.UTF-8

Затем выйдите из системы и войдите снова, и проверьте результат с помощью:

locale

Ответ или решение

Чтобы установить локаль на Debian/Ubuntu без интерактивного ввода, вы можете воспользоваться несколькими простыми командами в рамках вашего скрипта. В данной инструкции мы опишем, как выбрать локаль en_US.UTF-8, сделать её системной по умолчанию и отключить все остальные локали. Мы также добавим шаг для верификации, что файл /etc/default/locale содержит только одну запись с LANG=en_US.UTF-8.

Установка локали без интерактивного ввода

  1. Установка необходимых пакетов.
    Прежде всего, убедитесь, что пакет locales установлен. Это можно сделать с помощью следующей команды, которая подойдет для неинтерактивного запуска:

    apt-get update && apt-get install -y locales
  2. Настройка файла locale.gen.
    Используя sed, вы можете автоматически раскомментировать нужную локаль в файле /etc/locale.gen. Для этого выполните следующую команду:

    sed -i 's/# en_US.UTF-8/en_US.UTF-8/' /etc/locale.gen
  3. Обновление локалей.
    После этого вам нужно сгенерировать локали:

    locale-gen
  4. Установка локали по умолчанию.
    Теперь создайте или обновите файл /etc/default/locale, чтобы задать значение переменной LANG. Для этого выполните:

    echo 'LANG="en_US.UTF-8"' > /etc/default/locale
  5. Обновление локали.
    Команда update-locale также поможет сделать локаль обязательной для использования:

    update-locale LANG=en_US.UTF-8

Верификация настроек

Для проверки того, что файл /etc/default/locale содержит ожидаемую запись, можно воспользоваться следующей командой:

grep -q '^LANG="en_US.UTF-8"$' /etc/default/locale && echo "Настройка успешно выполнена" || echo "Ошибка в настройке"

Полный скрипт

Объединив все вышеперечисленные команды, вот как может выглядеть полный скрипт, который вы можете использовать:

#!/bin/bash

# Установка необходимых пакетов
apt-get update && apt-get install -y locales

# Настройка локалей
sed -i 's/# en_US.UTF-8/en_US.UTF-8/' /etc/locale.gen
locale-gen

# Установка локали по умолчанию
echo 'LANG="en_US.UTF-8"' > /etc/default/locale
update-locale LANG=en_US.UTF-8

# Верификация
if grep -q '^LANG="en_US.UTF-8"$' /etc/default/locale; then
    echo "Настройка локали успешно выполнена."
else
    echo "Ошибка в настройке локали."
fi

Заключение

Приведенные шаги позволят вам программно установить и настроить локаль на системах Debian и Ubuntu без необходимости вводить команды вручную. Это особенно полезно для автоматизации процессов в средах, таких как Docker или системы с массовым развертыванием. По завершении настройки рекомендуется перезагрузить систему или выйти из текущей сессии и войти снова, чтобы изменения вступили в силу.

Оцените материал
Добавить комментарий

Капча загружается...