Jak ustawić ustawienia regionalne w sposób nieinteraktywny na Debian / Ubuntu?

33

Zazwyczaj biegam aptitude -y install localesnastępnie dpkg-reconfigure localesskonfigurować ustawienia regionalne.

Teraz chcę umieścić go w skrypcie powłoki, jak mogę w sposób niezawodny wykonywać następujące czynności automatycznie / nieinteraktywnie?

  • Wybierz en_US.UTF-8i ustaw jako domyślny system
  • Wyłącz wszystkie inne ustawienia regionalne
  • (Opcjonalnie) Sprawdź, czy /etc/default/localezawiera jednorazowy wpis zgodny z LANG=en_US.UTF-8oczekiwaniami
kenn
źródło

Odpowiedzi:

13

Zobacz locale-gen :

 locale-gen --purge en_US.UTF-8

i

 echo -e 'LANG="en_US.UTF-8"\nLANGUAGE="en_US:en"\n' > /etc/default/locale
Kamień
źródło
1
Dzięki, ale dostaję File "/usr/share/apt-listchanges/ALChacks.py", line 32, in <module> sys.stderr.write(_("Can't set locale; make sure $LC_* and $LANG are correct!\n"))...
kenn
Spróbuj LANG = en_US.UTF-8 locale-gen --purge en_US.UTF-8
Stone
Dziś rano, z czystym stanem VM, zadziałało! Dzięki!
kenn
Hmm… kiedy uruchomisz locale-gen --purge en_GB.UTF-8czystą instalację, otrzymasz nieoczekiwany wynik: Generating locales (this might take a while)... en_US.UTF-8... done Generation complete.Jakieś pomysły, jak ustawić listę ustawień narodowych tak, jak robisz w dpkg-rekonfiguruj ustawienia regionalne nieinteraktywnie?
Benjamin Nolan
Oba wydały pozwolenie, odmówiono błędów ...
Cerin
47

Nie można uzyskać powyższej odpowiedzi do działania. Zamiast tego używam tej metody (w przypadku plików Docker):

# Configure timezone and locale
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
źródło
3
Plik dokowany jest dokładnie tym, czego potrzebowałem. Dzięki.
peedee
5
Nie należy odnosić się do innych odpowiedzi jako „powyżej”, „poniżej” lub podobnych. Odpowiedzi zmieniają się, gdy ludzie głosują na nich, akceptują je, usuwają lub po prostu wybierają różne zamówienia. Zawsze używaj nazwiska osoby, która opublikowała odpowiedź, lub jeszcze lepiej, użyj linku udostępniania pod odpowiedzią, którą komentujesz, aby wyraźnie połączyć się z odpowiedzią.
rjmunro
Nieco starsza wersja tej odpowiedzi - specjalnie dla Dockerfiles. EDYCJA: ponieważ nowe linie nie działają tutaj, proszę odnieść się do mojej odpowiedzi serverfault.com/a/801162/89669
mafrosis
Musiałem mieć en_GB.UTF-8skonfigurowane ustawienia regionalne w CircleCI - to była najlepsza odpowiedź, która działała. Mając nadzieję, że z powodu tego komentarza Google może pokazać, że jest to istotne, gdy ludzie próbują wyszukać problem, który miałem.
Alex Szabó
echo 'LANG = "nb_NO.UTF-8"'> / etc / default / locale jest redundantne z aktualizacją locale LANG = nb_NO.UTF-8
otonglet
7

Aby zmienić konfigurację strefy czasowej i ustawień regionalnych w sposób nieinteraktywny, z poziomu skryptu, oto, co działa dla mnie (pod Debianem):

  • Aby skonfigurować strefę czasową, najpierw tworzę „/ etc / localtime” jako miękki link do odpowiedniego pliku zoneinfo w katalogu „/ usr / share / zoneinfo”. Następnie uruchamiam polecenie dpkg-rekonfiguruj i wszystko zostanie wprowadzone na miejsce. Aby na przykład skonfigurować strefę czasową „Europa / Bruksela”:

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

    (Zauważ, że AREA to podkatalog w „/ usr / share / info”, a ZONE to plik w podkatalogu AREA).

  • Aby skonfigurować ustawienia narodowe, najpierw uruchamiam skrypt sed , który utworzy nową kopię pliku „/etc/locale.gen” na podstawie zawartości pliku „/ usr / share / i18n / SUPPORTED”. Każdy wiersz z pliku wejściowego zostanie skopiowany, ale zostanie przekształcony w komentarz, chyba że jest to wpis ustawień regionalnych UTF-8 dla języka, który chcę udostępnić w moim systemie (np. Angielski, holenderski, francuski, i niemiecki):

    sed --regexp-extended --expression='
    
       1  {
             i\
    # This file lists locales that you wish to have built. You can find a list\
    # of valid supported locales at /usr/share/i18n/SUPPORTED, and you can add\
    # user defined locales to /usr/local/share/i18n/SUPPORTED. If you change\
    # this file, you need to rerun locale-gen.\
    \
    
    
          }
    
       /^(en|nl|fr|de)(_[[:upper:]]+)?(\.UTF-8)?(@[^[:space:]]+)?[[:space:]]+UTF-8$/!   s/^/# /
    
    ' /usr/share/i18n/SUPPORTED >  /etc/locale.gen

    Następnie ustawiam domyślne ustawienia regionalne środowiska w bazie danych debconf, np. Na brytyjski angielski :

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

    Następnie usuwam istniejący plik „/ etc / default / locale” (aby upewnić się, że jego stara zawartość nie będzie kolidować z moimi nowymi ustawieniami) i uruchamiam polecenie dpkg-rekonfiguruj, aby wygenerować wszystkie ustawienia narodowe wybrane przez skrypt sed , i aby utworzyć nowy plik „/ etc / default / locale” z samym wpisem, aby ustawić zmienną „LANG” na wybrane przeze mnie domyślne ustawienia regionalne środowiska:

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

    Następnie, w zależności od moich wymagań, mogę chcieć uruchomić kilka poleceń locale aktualizacji , aby zastąpić np. Zmienne wpływające na formatowanie wartości i ustawić je na inne locale (takie jak irlandzki angielski ):

    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'

    (Mógłbym określić wszystkie te parametry przy jednym wywołaniu polecenia update-locale , ale najwyraźniej kolejność zapisywania wpisów w pliku „/ etc / default / locale” jest nieprzewidywalna, jeśli to zrobię. wolę, aby zawsze były w tej samej kolejności, dlatego generuję je jeden po drugim).

    I na koniec, mogę chcieć uruchomić locale aktualizacji po raz ostatni , aby skonfigurować zmienną LANGUAGE (tj. Listę języków, w których chcę wyświetlać przetłumaczalne wiadomości tekstowe):

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

Rzuć to wszystko razem w skrypt bash, a będziesz mógł łatwo zmienić ustawienia regionalne za pomocą prostego uruchomienia skryptu, który nie będzie wymagał dalszej interakcji użytkownika.

Z mojego doświadczenia wynika jednak, że nowe ustawienia nie zostaną całkowicie aktywowane, dopóki nie uruchomisz ponownie systemu dwa razy (przynajmniej na Debian Jessie Xfce). Po pierwszym ponownym uruchomieniu menedżer logowania przejmie nowe ustawienia w porządku, ale po zalogowaniu sesja użytkownika będzie nadal korzystać ze starych ustawień; następnie po drugim ponownym uruchomieniu sesja użytkownika również przyjmie nowe ustawienia.

luvr
źródło
7

Na podstawie dobrej pracy w odpowiedzi @ EirikW. Specyficzne dla Dockerfile:

ENV LANG=en_GB.UTF-8
RUN apt-get install -y locales && \
    sed -i -e "s/# $LANG.*/$LANG.UTF-8 UTF-8/" /etc/locale.gen && \
    dpkg-reconfigure --frontend=noninteractive locales && \
    update-locale LANG=$LANG
mafroza
źródło
1
Wolę ustawić ENV po, w przeciwnym razie pojawi się ten błąd: „perl: ostrzeżenie: ustawienie regionalne nie powiodło się. \ Perl: ostrzeżenie: Sprawdź, czy ustawienia regionalne: \ LANG =" en_US.UTF-8 "\ są obsługiwane i zainstalowany w twoim systemie. \ perl: ostrzeżenie: Powrót do standardowych ustawień regionalnych („C”).
otonglet
6

Dla mnie konieczne było ustawienie dodatkowych 3 zmiennych ENV:

# - Set the locale + timezone --------------------------------------------------
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

Jednak dzięki ErikWs za odpowiedź: ( https://serverfault.com/a/689947 )

Mike Mitterer
źródło
1
To jest jedyne rozwiązanie, które zadziałało dla mnie. Jestem w wersji Docker 17.06.1-ce, build 874a737
linuxatico