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"