Variáveis ​​de ambiente de um processo em execução no Unix?

231

Preciso solucionar alguns problemas relacionados a variáveis ​​de ambiente em um sistema Unix.

No Windows, posso usar uma ferramenta como o ProcessExplorer para selecionar um processo específico e exibir os valores de cada variável de ambiente.

Como posso realizar a mesma coisa no Unix? echoinge envcmd apenas mostram valores no momento, mas quero ver quais valores o processo em execução está usando atualmente.

m3rLinEz
fonte
2
Embora / proc / <pid> / environ tenha um tamanho de 0, ainda há informações lá. "Faz mais sentido se você pensar nisso como uma janela para o kernel. Na verdade, o arquivo não contém nenhum dado; ele apenas atua como um ponteiro para onde as informações reais do processo residem". [fonte ]
nevets1219 10/06/11

Respostas:

295
cat /proc/<pid>/environ

Se você deseja ter o (s) pid (s) de um determinado executável em execução, você pode, entre várias outras possibilidades, usar pidof:

AlberT$ pidof sshd   
30690 6512 

EDIT :

Cito totalmente os comentários de Dennis Williamson e Teddy para obter uma saída mais legível. Minha solução é a seguinte:

tr '\0' '\n' < /proc/<pid>/environ
drAlberT
fonte
46
Para torná-lo legível, converta os valores nulos em novas linhas:cat /proc/17330/environ | tr \\0 \\n
Dennis Williamson
32
Eu sempre façoxargs --null --max-args=1 echo < /proc/PID/environ
Teddy
7
melhor usar cordas, é rápido. Cat é ainda mais rápido :-)
Nikhil Mulley
3
O /procsistema de arquivos inteiro não é portátil.
Daniel H
6
Não entendo por que usar xargspara converter nulos em novas linhas é melhor do que usar tr. Alguém pode explicar isso para mim? Obrigado.
9786 Jonathan Hartley #
61

Como essa pergunta possui uma etiqueta unix e todo mundo fez um ótimo trabalho ao tratar da tag linux , você pode obter essas informações no OS X e em outros sistemas derivados do BSD usando

ps -p <PID> -wwwe

ou

ps -p <PID> -wwwE

e no Solaris com

/usr/ucb/ps -wwwe <PID>

O Solaris também suporta o /procdiretório se você não quiser se lembrar do pscomando obscuro .

Gerald Combs
fonte
3
Eu corro ps -p <PID> -wwwe no OS X 10.6. Eu recebo a lista de todos os processos em execução. o comando certo é com o sinalizador -E , não -e.
DrAlberT 18/09/09
1
Eu testei no OS X 10.4, mas não no 10.5. Atualizado em conformidade.
Gerald Combs
4
Isto não é perfeito. A opção -E reporta apenas as variáveis ​​de ambiente iniciais . Se as variáveis ​​foram alteradas pelo próprio processo em execução (por exemplo, através do uso da função POSIX putenv ()), as alterações não são refletidas na saída de ps -p <PID> -wwE.
Kal
1
Não ver vários processos que não pertencem a você parece um recurso desejável. É também o caso da resposta orientada a Linux do @ drAlberT usando /proc/PID/environ. Esses arquivos são legíveis apenas pelo proprietário do processo.
9787 Jonathan Hartley #
1
@yani É possível, mas é muito mais difícil, requer a conexão de um depurador ao processo em execução. Veja esta resposta: unix.stackexchange.com/a/70636
Kal
25

Como outros já mencionaram, no Linux, você pode procurar em / proc, mas existem, dependendo da versão do kernel, um ou dois limites:

Primeiro de tudo, o arquivo do ambiente contém o ambiente como parecia quando o processo foi gerado. Isso significa que quaisquer alterações que o processo possa ter feito em seu ambiente não serão visíveis em / proc:

$ cat /proc/$$/environ | wc -c
320
$ bash
$ cat /proc/$$/environ | wc -c
1270
$ 

O primeiro shell é um shell de logon e, inicialmente, possui um ambiente muito limitado, mas aumenta com o fornecimento, por exemplo, .bashrc, mas / proc não reflete isso. O segundo shell herda o ambiente maior desde o início, e é por isso que mostra em / proc.

Além disso, nos kernels antigos, o conteúdo do arquivo do ambiente é limitado ao tamanho da página (4K):

$ cat /proc/$$/environ | wc -c
4096
$ env | wc -c
10343
$ 

Em algum lugar entre 2.6.9 (RHEL4) e 2.6.18 (RHEL5), esse limite foi removido ...

Lasse
fonte
1
É possível obter as variáveis ​​ambientais de um processo remoto que foram definidas após a geração do processo? Entendo que no VFS, isso é mostrado com / proc / self / environ, mas apenas se estivermos dentro do processo. Mas como obter isso para um processo remoto?
GP92
11

uso correto das opções do BSD para fazer isso (pelo menos no Linux):

ps e $pid

ou

ps auxe  #for all processes

e sim, a página de manual do ps é bastante confusa. ( via )

raincrumb
fonte
Meu Ubuntu esmaga as variáveis ​​de ambiente diretamente na linha de comando, sem nem um espaço entre elas, e também trunca para uma linha na janela do terminal. Eu encontrei ps eww $pidcorrige o segundo problema.
user18911
1
@ user18911: Os ambientes têm um separador de caracteres nulos. Outras respostas nesta página mostram maneiras de usar xargsou trconvertê-las em novas linhas para facilitar a leitura. Você provavelmente percebeu isso nos quatro anos seguintes.
Jonathan Hartley
7
cat /proc/PID/environ

substitua o PID pelo PID do processo que você deseja ver. Todas as informações sobre um processo em execução estão no diretório / proc / PID /

exemplo: cat / proc / 32512 / environ

kargig
fonte
7

Retirado do wiki do Archlinux :

Você pode criar uma função temporária para analisar os valores /proc/<pid>/environ. No prompt do terminal:

envof() { sed 's/\x0/\n/g' /proc/${1}/environ; }

Depois, com o pid do processo que você deseja, basta usar:

envof <pid>
mwotton
fonte
6

No Linux, eu tentaria dar uma olhada

/proc/<pid>/environ
Joril
fonte
5

Para o Solaris 5.10, isso funciona:

pargs -e <PID>
Mykola Novik
fonte
5

Embora escassamente documentado, o conteúdo de /proc/<pid>/environapenas conterá o ambiente que foi usado para iniciar o processo.

Se você precisar inspecionar o estado atual do ambiente de um processo, uma maneira de fazer isso é usando gdb.

# Start gdb by attaching it to a pid or core file
gdb <executable-file> <pid or core file>

# Run the following script to dump the environment
set variable $foo = (char **) environ
set $i = 0
while ($foo[$i] != 0)
print $foo[$i++]
end
Michael Renner
fonte
3

E como meu trabalho me faz ser um fã do AIX, não vamos esquecer:

ps eww [pid]

Ou como a página de manual chama "Berkeley Standards".

Por qualquer motivo, / proc / PID / environ não existe no AIX.

Corey S.
fonte
2

Se você deseja criar envsaída formatada como as variáveis ​​de ambiente para um processo arbitrário (PID), é possível criar um penv <pid>comando conveniente do bash (adaptado ao seu sistema operacional) e adicioná-lo ao seu .bashrc:

Linux adicione isso ao seu ~ / .bashrc:

penv () { 
    xargs --null --max-args=1 < /proc/$1/environ
}

O macOS / BSD adicione isso ao seu ~ / .bashrc:

penv() {
   ps eww -o command $1  | tr ' ' '\n'
}

Solaris adicione isso ao seu ~ / .bashrc:

penv() {
   pargs -e $1
}

Uso:

$ fonte $ HOME / .bashrc
$ pgrep VBoxSVC
10268
$ penv 10268
SSH_CONNECTION = 1.1.1.242 53960 1.1.1.91 22
GREP_COLORS = sl = 49; 39: cx = 49; 39: mt = 49; 38; 5; 167; 1: fn = 49; 39; 1: ln = 49; 39: bn = 49; 39: se = 50; 39.
LANG = pt_BR.UTF-8
EDITOR = vim
XDG_SESSION_ID = 106
USER = raiz
PWD = / raiz
HOME = / root
SSH_CLIENT = 1.1.1.242 53960 22
SSH_TTY = / dev / pts / 3
CORREIO = / var / mail / root
TERM = xterm-256 cores
SHELL = / bin / bash
SHLVL = 1
LOGNAME = root
DBUS_SESSION_BUS_ADDRESS = unix: caminho = / run / user / 0 / bus
XDG_RUNTIME_DIR = / run / user / 0
PATH = / root / bin: / bin: / sbin: / usr / bin: / usr / sbin: / usr / local / bin: / usr / local / sbin :.
VBOX_LOG_FLAGS = thread tsc
VBOX_LOG = -todos + dev_vmm_backdoor.elf + dev_vmm.elf
luz clara
fonte
0

Uma solução para Mac, provavelmente outros BSDs também podem ser algo como

pid=28369; ps e $pid | cut -c$(expr 1 + $(ps p $pid|tail +2|wc -c))-

As variáveis ​​de ambiente são anexadas à linha de comando, isso remove a linha de comando e só temos as variáveis ​​de ambiente restantes.

Não é perfeito porque eles são separados por espaço e não por LF

Erik Martino
fonte
-1

/ proc / PID / environ

para isso, primeiro precisamos identificar o PID do processo. para isso você pode usar o comando ps

varun
fonte