conjunto LC_ * mas não LC_ALL

12

Eu gostaria de ter uma localidade alemã (Á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). Eu percebi que a maneira correta de conseguir isso é definir as variáveis LC_ da seguinte maneira no meu .bashrc (por favor me corrija se eu estiver errado):

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

Existe uma maneira mais elegante de definir LC_ $ everythingelse em vez de definir cada valor único? A configuração 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, então alterar as configurações de todo o sistema não é uma opção.

    
por Heinzi 20.06.2011 / 11:27

2 respostas

14

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

  • LANG , a configuração de fallback, se você não tiver especificado um valor para uma categoria. É induzido pelos usuários para indicar sua localidade de uma maneira simples.
  • LC_xxx para cada categoria ( xxx pode ser MESSAGES , TIME , etc.).
  • LC_ALL substitui todas as configurações. É uma maneira de os aplicativos substituírem todas as configurações para trabalhar em uma localidade conhecida (geralmente C , a localidade padrão), normalmente para que vários comandos produzam saída em um formato conhecido.

Assim, você pode definir LANG=de_AT.UTF-8 e LC_MESSAGES=C ( C é a localidade padrão e significa não traduzido; en_US é geralmente idêntico a C para mensagens).

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

  • LC_COLLATE é o caractere pedido de agrupamento . Não é muito útil porque indica apenas como classificar os caracteres, não como ordenar as strings. Ferramentas que sabem classificar strings 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 (tente echo B | LC_COLLATE=en_US grep '[a-z]' ).
  • LC_NUMERIC indica como exibir números. Em particular, em muitos idiomas, os números de ponto flutuante usam , em vez de . como ponto decimal. Mas a maioria dos programas que analisam números esperam um . e tratam um , como um separador de campos.

Então, eu recomendo para

  • seja explicitamente LC_COLLATE=C LC_NUMERIC=_C ,
  • ou deixe LANG não definido e defina apenas um valor para as categorias úteis ( LC_MESSAGES , LC_TIME , LC_PAPER , mais LC_CTYPE (cujo valor pode variar dependendo do seu terminal)).

Mais LANGUAGE com o GNU libc. Se você não ouviu falar sobre isso, você não está perdendo muito.

    
por 20.06.2011 / 23:11
9

O local da página man man (7) diz:

the default locale [...] is determined using the following steps:

  1. If there is a non-null environment variable LC_ALL, the value of LC_ALL is used.

  2. If an environment variable with the same name as one of the categories [LC_*] above exists and is non-null, its value is used for that category.

  3. If there is a non-null environment variable LANG, the value of LANG is used.

Assim, você pode usar o LANG como uma espécie de análogo de baixa precedência de LC_ALL: defina o valor de LANG como de_AT e LC_MESSAGES como 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"
    
por 20.06.2011 / 14:13