defina LC_ * mas não LC_ALL

14

Gostaria de ter um código de idioma alemão (Áustria) (tamanho de papel A4, 24 horas, aaaa-mm-dd), mas uma interface de usuário em inglês (não gosto de traduções ruins). Imaginei que a maneira correta de conseguir isso é definir as LC_variáveis ​​da seguinte maneira em minha .bashrc(por favor, corrija-me se estiver errado):

LC_MESSAGES=en_US.UTF-8
LC_$everythingelse=de_AT.UTF-8

Existe uma maneira mais elegante de definir LC_ $ everythingelse ao invés de definir todos os valores? Definir LC_ALL não é uma opção, pois tem precedência sobre LC_MESSAGES:

$ export LC_ALL=de_AT.UTF_8
$ export LC_MESSAGES=en_US.UTF_8
$ echo $LC_MESSAGES
en_US.UTF_8
$ locale | grep LC_MESSAGES
LC_MESSAGES="de_AT.UTF_8"

PS: É uma máquina compartilhada e eu não sou sudoer, portanto, alterar as configurações do sistema não é uma opção.

Heinzi
fonte

Respostas:

16

Existem três conjuntos de configurações de localidade¹:

  • LANG, a configuração de fallback, se você não especificou um valor para uma categoria. É recomendado que os usuários indiquem seus códigos de idioma de maneira simples.
  • LC_xxxPara cada categoria ( xxxpode ser MESSAGES, TIME, etc.).
  • LC_ALLsubstitui todas as configurações. É uma maneira de os aplicativos substituirem todas as configurações para trabalhar em um local conhecido (normalmente C, o local padrão), normalmente para que vários comandos produzam saída em um formato conhecido.

Assim, você pode definir LANG=de_AT.UTF-8e LC_MESSAGES=C( Cé o código do idioma padrão e significa não traduzido; en_USgeralmente é idêntico ao Cdas mensagens).

No entanto, existem duas categorias em que eu não recomendo alterar o padrão, porque ele quebra muitos programas:

  • LC_COLLATEé a ordem de agrupamento de caracteres . Não é muito útil porque indica apenas como classificar caracteres, não como classificar cadeias. Ferramentas que sabem como classificar seqüências de caracteres não usam LC_COLLATE. Além disso, muitas ferramentas esperam coisas como " [a-z]corresponde a todas as 26 letras minúsculas ASCII e nenhum outro caractere ASCII", mas isso não é verdade na maioria das localidades não padrão (try echo B | LC_COLLATE=en_US grep '[a-z]').
  • LC_NUMERICindica como exibir números. Em particular, em muitos idiomas, os números de ponto flutuante usam um ,e não .o ponto decimal. Mas a maioria dos programas que analisam números esperam .e tratam a ,como um separador de campos.

Então eu recomendo

  • explicitamente LC_COLLATE=C LC_NUMERIC=_C,
  • ou deixar LANGdesactivado e só definir um valor para as categorias úteis ( LC_MESSAGES, LC_TIME, LC_PAPER, mais LC_CTYPE(cujo valor pode variar dependendo do seu terminal)).

¹ Além disso, LANGUAGEcom GNU libc. Se você não ouviu falar, não está perdendo muito.

Gilles 'SO- parar de ser mau'
fonte
Obrigado pela resposta detalhada e pelas explicações! Porém, tentarei um LC_NUMERIC localizado, já que o teclado numérico nos teclados alemães ,substitui um .(infelizmente), portanto, inserir números com um ponto é inconveniente (e a maioria dos aplicativos parece funcionar bem com um LC_NUMERIC não padrão). Eu não entendo completamente o seu exemplo LC_COLLATE: No meu sistema, o exemplo que você deu não corresponde B.
Heinzi
@ Heinzi LC_COLLATE afeta (deve) os intervalos de caracteres?
Gilles 'SO- stop be evil'
10

O código do idioma da página de manual (7) diz:

a localidade padrão [...] é determinada usando as seguintes etapas:

  1. Se houver uma variável de ambiente não nula LC_ALL, o valor de LC_ALL será usado.

  2. Se uma variável de ambiente com o mesmo nome de uma das categorias [LC_ *] acima existir e for não nula, seu valor será usado para essa categoria.

  3. Se houver uma variável de ambiente não nula LANG, o valor de LANG será usado.

Portanto, você pode usar LANG como uma espécie de análogo de baixa precedência de LC_ALL: defina o valor de LANG como de_ATe LC_MESSAGES para en_US:

$ env LC_MESSAGES=en_US.UTF-8 LANG=de_AT.UTF-8 locale | egrep '(MESSAGES|PAPER)'
LC_MESSAGES=en_US.UTF-8
LC_PAPER="de_AT.UTF-8"
Riccardo Murri
fonte