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
[...]