¿Para qué sirve el C
valor LC_ALL
en sistemas tipo Unix?
Sé que obliga a la misma configuración regional para todos los aspectos, pero ¿qué hace C
?
environment-variables
locale
jcubic
fuente
fuente
xclock
advertencia (Missing charsets in String to FontSet conversion
), será mejor si lo utilizaLC_ALL=C.UTF-8
para evitar problemas con cirílico. Para establecer esta variable de entorno, debe agregar la siguiente línea al final del~/.bashrc
archivo -export LC_ALL=C.UTF-8
Respuestas:
Obliga a las aplicaciones a usar el idioma predeterminado para la salida:
y obliga a la clasificación a ser byte-sabio:
fuente
LC_ALL
es la variable de entorno que anula todas las demás configuraciones de localización ( excepto$LANGUAGE
en algunas circunstancias ).Los diferentes aspectos de las localizaciones (como el separador de miles o el carácter de punto decimal, el conjunto de caracteres, el orden de clasificación, los nombres de mes, día, idioma o mensajes de aplicación como mensajes de error, símbolo de moneda) se pueden configurar utilizando algunas variables de entorno.
Por lo general, establecerá
$LANG
su preferencia con un valor que identifica su región (comofr_CH.UTF-8
si se encuentra en Suiza francófona, utilizando UTF-8). LasLC_xxx
variables individuales anulan un cierto aspecto.LC_ALL
los anula a todos. Ellocale
comando, cuando se llama sin argumento, ofrece un resumen de la configuración actual.Por ejemplo, en un sistema GNU, obtengo:
Puedo anular una configuración individual con, por ejemplo:
O:
O anule todo con LC_ALL.
En un script, si desea forzar una configuración específica, ya que no sabe qué configuraciones ha forzado el usuario (posiblemente LC_ALL también), su mejor opción, la más segura y, en general, única es forzar LC_ALL.
La
C
configuración regional es una configuración especial que debe ser la configuración regional más simple. También podría decir que si bien las otras configuraciones regionales son para humanos, la configuración regional C es para computadoras. En la configuración regional C, los caracteres son bytes individuales, el conjunto de caracteres es ASCII (bueno, no es obligatorio, pero en la práctica estará en los sistemas que la mayoría de nosotros usará), el orden de clasificación se basa en los valores de bytes, el idioma suele ser el inglés de EE. UU. (aunque para los mensajes de la aplicación (a diferencia de los nombres de mes o día o los mensajes de las bibliotecas del sistema), queda a discreción del autor de la aplicación) y los elementos como los símbolos de moneda no están definidos.En algunos sistemas, hay una diferencia con la configuración regional POSIX donde, por ejemplo, el orden de clasificación para caracteres no ASCII no está definido.
Generalmente ejecuta un comando con LC_ALL = C para evitar que la configuración del usuario interfiera con su script. Por ejemplo, si desea
[a-z]
hacer coincidir los 26 caracteres ASCII dea
az
, debe configurarLC_ALL=C
.En sistemas GNU,
LC_ALL=C
yLC_ALL=POSIX
(oLC_MESSAGES=C|POSIX
) anular$LANGUAGE
, mientrasLC_ALL=anything-else
que no lo haría.Algunos casos en los que normalmente necesita configurar
LC_ALL=C
:sort -u
osort ... | uniq...
. En muchos entornos locales distintos de C, en algunos sistemas (especialmente los GNU), algunos caracteres tienen el mismo orden de clasificación .sort -u
no informa líneas únicas, sino una de cada grupo de líneas que tienen el mismo orden de clasificación. Entonces, si desea líneas únicas, necesita una configuración regional donde los caracteres son byte y todos los caracteres tienen un orden de clasificación diferente (lo queC
garantiza la configuración regional).=
operador de POSIX compatibleexpr
u==
operador de POSIX compatibleawk
s (mawk
ygawk
no son POSIX en ese sentido), que no comprueban si dos cadenas son idénticas sino si clasifican lo mismo.grep
. Si quiere hacer coincidir una letra en el idioma del usuario, usegrep '[[:alpha:]]'
y no modifiqueLC_ALL
. Pero si desea hacer coincidir losa-zA-Z
caracteres ASCII, necesitaLC_ALL=C grep '[[:alpha:]]'
oLC_ALL=C grep '[a-zA-Z]'
¹.[a-z]
coincide con los caracteres que se ordenan despuésa
y antesz
(aunque con muchas API es más complicado que eso). En otros lugares, generalmente no sabes cuáles son. Por ejemplo algunos locales ignoran caso para clasificar de manera[a-z]
en algunas APIs comobash
patrones, podría incluir[B-Z]
o[A-Y]
. En muchos entornos locales UTF-8 (inclusoen_US.UTF-8
en la mayoría de los sistemas),[a-z]
se incluirán las letras latinas dea
ay
con diacríticos pero no los dez
(ya quez
tipo antes que ellos) que no puedo imaginar que sea lo que quieres (¿por qué querrías incluirloé
y noź
?).aritmética de coma flotante en
ksh93
.ksh93
honra ladecimal_point
puesta en escenaLC_NUMERIC
. Si escribe un script que contienea=$((1.2/7))
, dejará de funcionar cuando lo ejecute un usuario cuya configuración regional tenga una coma como separador decimal:Entonces necesitas cosas como:
Como nota al margen: el
,
separador decimal entra en conflicto con el,
operador aritmético, lo que puede causar aún más confusión.grep '<.*>'
para buscar líneas que contengan un<
, el>
par no funcionará si está en un entorno local UTF-8 y la entrada está codificada en un conjunto de caracteres de 8 bits de un solo byte como iso8859-15. Esto se debe a que.
solo los caracteres coincidentes y los caracteres no ASCII en iso8859-15 probablemente no formen un carácter válido en UTF-8. Por otro lado,LC_ALL=C grep '<.*>'
funcionará porque cualquier valor de byte forma un carácter válido en laC
configuración regional.Cualquier momento en el que procese datos de entrada o datos de salida que no estén destinados a / para un humano. Si está hablando con un usuario, es posible que desee usar su convención e idioma, pero, por ejemplo, si genera algunos números para alimentar alguna otra aplicación que espere puntos decimales en inglés o nombres de meses en inglés, querrá establecer LC_ALL = C:
Eso también se aplica a cosas como la comparación entre mayúsculas y minúsculas (como en
grep -i
) y la conversión de mayúsculas y minúsculas (awk
'stoupper()
,dd conv=ucase
...). Por ejemplo:no se garantiza que coincida
I
en la configuración regional del usuario. En algunas configuraciones regionales turcas, por ejemplo, no lo hace, ya que las mayúsculasi
estánİ
(tenga en cuenta el punto) y las minúsculasI
estánı
(tenga en cuenta el punto que falta).¹ Dependiendo de la codificación del texto, eso no es necesariamente lo correcto. Eso es válido para UTF-8 o juegos de caracteres de un solo byte (como iso-8859-1), pero no necesariamente para juegos de caracteres multibyte que no sean UTF-8.
Por ejemplo, si está en un
zh_HK.big5hkscs
entorno local (Hong Kong, utilizando la variante de Hong Kong de la codificación de caracteres chinos BIG5), y desea buscar letras en inglés en un archivo codificado en esos conjuntos de caracteres, haciendo lo siguiente:o
estaría mal, porque en ese juego de caracteres (y muchos otros, pero apenas utilizado desde que salió UTF-8), muchos caracteres contienen bytes que corresponden a la codificación ASCII de caracteres A-Za-z. Por ejemplo, todos
A䨝䰲丕乙乜你再劀劈呸哻唥唧噀噦嚳坽
(y muchos más) contienen la codificación deA
.䨝
es 0x96 0x41, yA
es 0x41 como en ASCII. Entonces nuestroLC_ALL=C grep '[a-zA-Z]'
coincidiría en esas líneas que contienen esos caracteres, ya que malinterpretaría esas secuencias de bytes.funcionaría, pero solo si
LC_ALL
no se establece de otra manera (lo que anularíaLC_COLLATE
). Entonces puede terminar teniendo que hacer:si desea buscar letras en inglés en un archivo codificado en la codificación de la configuración regional.
fuente
C
configuración regional solo es necesaria para admitir el "juego de caracteres portátil" (ASCII 0-127), y el comportamiento de los caracteres> 127 no está técnicamente especificado . En la práctica, la mayoría de los programas los tratarán como datos opacos y los pasarán como usted describió. Pero no todos: en particular, Ruby puede ahogarse en los datos de caracteres con bytes> 127 si se ejecuta en laC
configuración regional. Sinceramente, no sé si eso es técnicamente "conforme", pero lo hemos visto en la naturaleza .perl
's\x{7FFFFFFFFFFFFFFF}
) y aunque el rango de puntos de código Unicode se ha restringido arbitrariamente a U + 10FFFF (debido a la limitación de diseño UTF-16), algunas herramientas aún reconocen / producen caracteres de 6 bytes. Eso es lo que quise decir con caracteres de 6 bytes. En la semántica de Unix, un carácter es un punto de código. Sus más de un "carácter" de punto de código se mencionan más generalmente como grupos de gráficos para desambiguarse de los caracteres.C
es la configuración regional predeterminada, "POSIX" es el alias de "C". Supongo que "C" se deriva de ANSI-C. Quizás ANSI-C defina la configuración regional "POSIX".fuente
C
nombre de la localidad se derive de "ANSI C".Por lo que puedo decir, OS X usa el orden de clasificación de puntos de código en las configuraciones regionales UTF-8, por lo que es una excepción a algunos de los puntos mencionados en la respuesta de Stéphane Chazelas.
Esto imprime 26 en OS X y 310 en Ubuntu:
El siguiente código no imprime nada en OS X, lo que indica que la entrada está ordenada. Los seis caracteres sustitutos que se eliminan provocan un error de secuencia de bytes ilegal.
El siguiente código no imprime nada en OS X, lo que indica que no hay dos puntos de código consecutivos (al menos entre U + 000B y U + D7FF) que tengan el mismo orden de clasificación.
(Los ejemplos anteriores se usan
%b
porqueprintf \\U25
resultan en un error en zsh).Algunos caracteres y secuencias de caracteres que tienen el mismo orden de clasificación en los sistemas GNU no tienen el mismo orden de clasificación en OS X. Esto imprime ① primero en OS X (usando OS X
sort
o GNUsort
) pero ② primero en Ubuntu:Esto imprime tres líneas en OS X (usando OS X
sort
o GNUsort
) pero una línea en Ubuntu:fuente
Parece que también
LC_COLLATE
controla el "orden alfabético" utilizado por ls. La configuración regional de EE. UU. Se ordenará de la siguiente manera:básicamente ignorando los períodos. Quizás prefieras:
Ciertamente lo hago. Establecer
LC_COLLATE
paraC
lograr esto. Tenga en cuenta que también ordenará minúsculas después de todas las mayúsculas:fuente