Com o GNU xargs
no Linux:
xargs -r0a "/proc/$pid/environ" sh -c 'exec env -i -- "$@" locale' sh
Executaria locale
em uma cópia do ambiente em que o processo de pid $pid
passou para o último comando executado.
Note que locale
sendo externo, ele só se preocupa com variáveis de ambiente, não com variáveis de shell se elas não foram exportadas.
O próprio shell pode ter suas configurações de localização afetadas, mesmo se as variáveis LC_*
, LANG
, LANGUAGE
não forem exportadas.
Algumas notas de cautela:
- Os programas que usam localização geralmente usam
setlocale(LC_ALL, "")
para inicializar todas suas configurações de localização com base no ambiente, mas não precisam. - Eles podem chamar
setlocale()
com parâmetros diferentes (improváveis). - Eles podem chamá-lo antes de depois de modificar seu ambiente (com APIs como
putenv()
/setenv()
). - Esses
putenv()
/setenv()
tradicionalmente não modificam a área exposta por/proc/$pid/environ
, mas o IIRC está mudando nas versões recentes do Linux e da GNU libc. - Independentemente daqueles
putenv()
/setenv()
, o processo pode acabar modificando sua área da pilha exposta por/proc/$pid/environ
(improvável).
Outra opção seria anexar o gdb ao processo e fazer:
call system("locale")
Isso é bastante intrusivo.
Essa pessoa usaria o ambiente preparado pelo próprio processo (assumindo que ele usa environ
e / ou putenv()
/ setenv()
, o que nem todas as aplicações, especialmente shells, por exemplo, fazem).
Com o gdb, você também pode consultar as configurações de localização diretamente chamando setlocale()
para cada categoria de local com um segundo argumento NULL.
Para saber o valor de uma determinada categoria:
$ printf '#include <locale.h>\nLC_COLLATE\n' | gcc -E -x c - | tail -n 1
3
Para imprimir o nome da localidade em gdb
:
(gdb) p (char*)setlocale(3, 0)
$3 = 0xde8f40 "en_GB.UTF-8"
Ou:
(gdb) x/s setlocale(3, 0)
0xde8f40: "en_GB.UTF-8"