Variáveis ambientais atuais de um processo

3

Esta questão está relacionada com esta resposta .

É possível obter as variáveis ambientais atuais (não iniciais) de um processo fazendo um processo filho e verificando suas variáveis ambientais iniciais?

A ideia é que o ambiente inicial de um processo filho seja herdado do ambiente atual do pai.

    
por TheMeaningfulEngineer 16.07.2013 / 09:21

2 respostas

4

O ambiente é uma lista de strings passadas ao longo da chamada do sistema execve , assim como a lista de argumentos. Período. O que os aplicativos fazem com essa lista de strings que recebe é com o aplicativo.

Agora, por convenção, essa lista é geralmente usada de maneira diferente da lista de argumentos. Os programas geralmente lembram a lista de variáveis de ambiente que recebem e reutilizam o mesmo ao executar outro comando.

Eles têm as funções da biblioteca C para ajudá-los a fazer isso: o ambiente é disponibilizado como environ e você pode recuperar e modificar essa lista (a cópia da lista de variáveis de ambiente que recebeu) com getenv , setenv , putenv e funções como execvp , execl , system , popen ... usam essa variável environ ao executar comandos (chame execve com o environ estão acompanhando).

Agora os aplicativos não precisam usar essa API. Eles podem usar seu próprio caminho para gerenciar a lista de variáveis de ambiente. Shells, por exemplo, mapeiam variáveis de ambiente para variáveis do shell e provavelmente não usam funções putenv / setenv libc. perl tem sua matriz associativa %ENV e assim por diante.

Você sempre pode usar gdb para anexar a um processo e chamá-lo de system("env > /tmp/some-file") (supondo que eles estejam vinculados dinamicamente à libc), mas você não tem garantia de que env obterá o mesmo ambiente que outro comando seria obtido se o comando ao qual você está anexando estivesse executando-o a seu próprio modo (pense em shells, por exemplo). (também note que system() inicia um shell (para interpretar a linha de comando) e os shells podem alterar seu ambiente no início (tente por exemplo env -i sh -c env ).

$ sleep 100 &
[1] 17098
$ gdb --pid=$! /bin/sleep
[...]
(gdb) p environ[0]
$1 = 0x7fffd722d227 "STY=7498.pts-0.hostname"
(gdb) p environ[1]
$2 = 0x7fffd722d245 "TERM=screen-bce"
(gdb) call system("env > /tmp/some-file")
$4 = 0
(gdb) detach
Detaching from program: /bin/sleep, process 17098
(gdb) quit
$ cat /tmp/some-file
GNOME_KEYRING_PID=6850
SSH_AGENT_PID=6844
SHLVL=1
[...]
    
por 16.07.2013 / 10:25
0

Se você estiver executando o Linux ou um dos Unixes que possui um sistema de arquivos /proc , o ambiente de um processo estará em um dos arquivos por processo em /proc . Eu não tenho acesso a uma máquina Solaris agora, mas para Linux isso funcionou:

$ tr  '
$ tr  '%pre%' '\n' < /proc/$$/environ
' '\n' < /proc/$$/environ

Isso imprime as variáveis de ambiente do shell atual, mas $$ pode ser qualquer ID de processo a que seu ID de usuário tenha acesso.

Havia uma maneira de fazer isso no Solaris, mas era muito mais complicado. Eu acho que os BSDs têm um /proc mais parecido com o Linux.

    
por 16.07.2013 / 15:51