Como você define um código de idioma de maneira não interativa no Debian / Ubuntu?

33

Normalmente, eu corro aptitude -y install locales, em seguida, dpkg-reconfigure localespara configurar localidade.

Agora eu quero colocá-lo em um script de shell, como posso fazer o seguinte com segurança, de forma automática / não interativa?

  • Escolha en_US.UTF-8e defina-o como padrão do sistema
  • Desativar todos os outros locais
  • (Opcional) Verifique se /etc/default/localecontém uma entrada única LANG=en_US.UTF-8como esperado
Kenn
fonte

Respostas:

13

Consulte locale-gen :

 locale-gen --purge en_US.UTF-8

e

 echo -e 'LANG="en_US.UTF-8"\nLANGUAGE="en_US:en"\n' > /etc/default/locale
Pedra
fonte
1
Obrigado, mas eu estou ficando 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
Tente LANG = pt_BR.UTF-8 locale-gen --purge pt_US.UTF-8
Stone
Esta manhã, com um estado limpo de VM, funcionou! Obrigado!
kenn
Hmm… quando você executa locale-gen --purge en_GB.UTF-8uma instalação limpa, obtém uma saída inesperada: Generating locales (this might take a while)... en_US.UTF-8... done Generation complete.Alguma idéia de como definir a lista de códigos de idioma como você faz no código de configuração do dpkg-reconfigure de maneira não interativa?
Benjamin Nolan
Esta permissão ambos dão negado erros ....
Cerin
47

Não foi possível obter a resposta acima para o trabalho. Em vez disso, eu uso este método (para Dockerfiles):

# 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
fonte
3
Dockerfile é exatamente o que eu precisava disso. Obrigado.
Peedee
5
Por favor, não se refira a outras respostas como "acima", "abaixo" ou similar. As respostas mudam conforme as pessoas votam nelas, as aceitam, as excluem ou apenas escolhem pedidos diferentes. Sempre use o nome da pessoa que postou a resposta, ou melhor ainda, use o link de compartilhamento abaixo da resposta que você está comentando para vincular explicitamente à resposta.
Rjmunro 12/05
Versão ligeiramente mais organizada desta resposta - especificamente para Dockerfiles .. EDIT: como as novas linhas não funcionam aqui, consulte a minha resposta serverfault.com/a/801162/89669
mafrosis
Eu precisava ter en_GB.UTF-8o código de idioma configurado no CircleCI - essa era a melhor resposta que estava funcionando. Esperando que, devido a esse comentário, o Google possa mostrar isso como relevante quando as pessoas tentam procurar o problema que eu estava tendo.
Alex Szabó
echo 'LANG = "nb_NO.UTF-8"'> / etc / default / locale é redundante com update-locale LANG = nb_NO.UTF-8
otonglet
7

Para reconfigurar o fuso horário e as localidades de maneira não interativa, de dentro de um script, aqui está o que funciona para mim (no Debian):

  • Para configurar o fuso horário, primeiro crio '/ etc / localtime' como um link para o arquivo zoneinfo apropriado no diretório '/ usr / share / zoneinfo'. Então, eu executo o comando dpkg-reconfigure e tudo será colocado no lugar. Por exemplo, para configurar o fuso horário 'Europa / Bruxelas':

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

    (Observe que AREA é um subdiretório em '/ usr / share / info' e ZONE é um arquivo no subdiretório AREA).

  • Para configurar as localidades, primeiro executo um script sed que criará uma nova cópia do arquivo '/etc/locale.gen', com base no conteúdo do arquivo '/ usr / share / i18n / SUPPORTED'. Todas as linhas do arquivo de entrada serão copiadas, mas serão transformadas em comentários, a menos que seja uma entrada de uma localidade UTF-8 para um idioma que eu desejo disponibilizar no meu sistema (por exemplo, inglês, holandês, francês, e alemão):

    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

    Em seguida, defino o código de idioma do ambiente padrão no banco de dados debconf, por exemplo, para inglês britânico :

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

    Posteriormente, removo o arquivo '/ etc / default / locale' existente (apenas para garantir que seu conteúdo antigo não interfira nas minhas novas configurações) e execute o comando dpkg-reconfigure para gerar todos os códigos de idioma que o script sed selecionou e para criar um novo arquivo '/ etc / default / locale' com apenas uma entrada para definir a variável 'LANG' como o local do ambiente padrão selecionado:

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

    Então, dependendo dos meus requisitos, talvez eu queira executar alguns comandos update-locale , para substituir, por exemplo, as variáveis ​​que afetam a formatação dos valores e configurá-los para um local diferente (como o inglês irlandês ):

    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'

    (Eu poderia ter especificado todos esses parâmetros em uma única chamada do comando update-locale , mas, aparentemente, a ordem na qual as entradas são gravadas no arquivo '/ etc / default / locale' é imprevisível se eu fizer isso. prefiro que eles sempre estejam na mesma ordem, e é por isso que eu os gero um a um.)

    E, finalmente, convém executar o comando update-locale uma última vez, para configurar a variável LANGUAGE (ou seja, a lista de idiomas nos quais desejo que as mensagens de texto traduzíveis sejam exibidas):

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

Junte tudo isso em um script bash e poderá reconfigurar facilmente suas configurações de localidade com uma simples execução do script, o que não exigirá nenhuma interação adicional do usuário.

Na minha experiência, no entanto, as novas configurações não serão totalmente ativadas até que você reinicie o sistema duas vezes (pelo menos no Debian Jessie Xfce). Após a primeira reinicialização, o gerenciador de login aceitará as novas configurações, mas após o login, sua sessão de usuário continuará usando as configurações antigas; depois da segunda reinicialização, sua sessão do usuário também fará as novas configurações.

luvr
fonte
7

Baseado no bom trabalho da resposta de @ EirikW. Específico para um 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
mafrosis
fonte
1
Prefiro definir a ENV depois, caso contrário, você receberá este erro: "perl: warning: Falha na configuração da localidade. \ Perl: warning: Verifique se as configurações da localidade: \ LANG =" en_US.UTF-8 "\ são suportadas e instalado no seu sistema. \ perl: warning: Voltando ao
código do
6

Para mim, foi necessário definir os 3 ENV-Vars adicionais:

# - 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

No entanto, obrigado a ErikWs por sua resposta: ( https://serverfault.com/a/689947 )

Mike Mitterer
fonte
1
Esta é a única solução que funcionou para mim, estou na versão Docker 17.06.1-ce, construção 874a737
linuxatico