Zmienne środowiskowe uruchomionego procesu w systemie Unix?

230

Muszę rozwiązać niektóre problemy związane ze zmiennymi środowiskowymi w systemie Unix.

W systemie Windows mogę użyć narzędzia, takiego jak ProcessExplorer, aby wybrać konkretny proces i wyświetlić wartości każdej zmiennej środowiskowej.

Jak mogę osiągnąć to samo na Uniksie? echoingi envcmd tylko pokazują wartości w chwili obecnej, ale chcę zobaczyć, jakich wartości używa aktualnie uruchomiony proces.

m3rLinEz
źródło
2
Mimo że / proc / <pid> / environment ma rozmiar 0, nadal są tam informacje. „Bardziej sensowne jest myślenie o nim jako o okienku do jądra. Plik tak naprawdę nie zawiera żadnych danych; działa jedynie jako wskaźnik miejsca, w którym znajdują się rzeczywiste informacje o procesie”. [źródło ]
nevets1219

Odpowiedzi:

295
cat /proc/<pid>/environ

Jeśli chcesz mieć pid (y) danego działającego pliku wykonywalnego, możesz, wśród wielu innych możliwości, użyć pidof:

AlberT$ pidof sshd   
30690 6512 

EDYCJA :

Całkowicie cytuję komentarze Dennisa Williamsona i Teddy'ego, aby uzyskać bardziej czytelny wynik. Moje rozwiązanie jest następujące:

tr '\0' '\n' < /proc/<pid>/environ
drAlberT
źródło
46
Żeby było czytelne, konwertować wartości null do nowej linii:cat /proc/17330/environ | tr \\0 \\n
Dennis Williamson
32
Zawsze tak robięxargs --null --max-args=1 echo < /proc/PID/environ
Teddy
7
lepiej używać ciągów, jest szybki. Kot jest jeszcze szybszy :-)
Nikhil Mulley
2
Cały /procsystem plików nie jest przenośny.
Daniel H
6
Nie rozumiem, dlaczego używanie xargsdo konwertowania wartości zerowych na znaki nowej linii jest lepsze niż używanie tr. Czy ktoś może to dla mnie rozłożyć? Dzięki.
Jonathan Hartley,
61

Ponieważ to pytanie ma znacznik unix, a wszyscy inni wykonali tak świetną robotę adresując znacznik linux , możesz uzyskać te informacje na OS X i innych systemach pochodzących z BSD za pomocą

ps -p <PID> -wwwe

lub

ps -p <PID> -wwwE

i na Solarisie z

/usr/ucb/ps -wwwe <PID>

Solaris obsługuje również /prockatalog, jeśli nie chcesz pamiętać psnieznanego polecenia.

Gerald Combs
źródło
3
II uruchom ps -p <PID> -wwwe na OS X 10.6. Otrzymuję listę wszystkich uruchomionych procesów. właściwe polecenie ma flagę -E , a nie -e.
drAlberT
1
Testowałem na OS X 10.4, ale nie 10.5. Zaktualizowano odpowiednio.
Gerald Combs,
4
To nie jest idealne. Opcja -E zgłasza tylko początkowe zmienne środowiskowe. Jeśli zmienne zostały zmienione przez sam uruchomiony proces (np. Za pomocą funkcji putenv () POSIX), zmiany nie są odzwierciedlone w wynikach ps -p <PID> -wwE.
Kal
1
Niezrozumienie różnych procesów, które nie są własnością użytkownika, wydaje się pożądaną funkcją. Dotyczy to również odpowiedzi zorientowanej na Linuksa @ drAlberT /proc/PID/environ. Pliki te są czytelne tylko dla właściciela procesu.
Jonathan Hartley,
1
@yani Jest to możliwe, ale jest o wiele trudniejsze, wymaga dołączenia debugera do uruchomionego procesu. Zobacz tę odpowiedź: unix.stackexchange.com/a/70636
Kal
25

Jak wspomnieli inni, w Linuksie możesz zajrzeć do / proc, ale istnieją, w zależności od wersji jądra, jedno lub dwa ograniczenia:

Po pierwsze, plik środowiska zawiera środowisko, w którym wyglądało, gdy proces się pojawił. Oznacza to, że wszelkie zmiany, które proces mógł wprowadzić w swoim otoczeniu, nie będą widoczne w / proc:

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

Pierwsza powłoka jest powłoką logowania i początkowo ma bardzo ograniczone środowisko, ale rozwija się poprzez pozyskiwanie np. .Bashrc, ale / proc tego nie odzwierciedla. Druga powłoka od samego początku dziedziczy większe środowisko, dlatego pokazuje się w / proc.

Ponadto w starszych jądrach zawartość pliku środowiska jest ograniczona do rozmiaru strony (4K):

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

Gdzieś pomiędzy 2.6.9 (RHEL4) a 2.6.18 (RHEL5) ten limit został usunięty ...

Lasse
źródło
1
Czy można uzyskać zmienne środowiskowe zdalnego procesu, które zostały ustawione po spawnowaniu procesu? Rozumiem, że w VFS jest pokazywany w / proc / self / Environment, ale tylko wtedy, gdy jesteśmy w trakcie procesu. Ale jak zdobyć to na zdalny proces?
GP92
11

poprawne użycie opcji BSD, aby to zrobić (przynajmniej na Linuksie):

ps e $pid

lub

ps auxe  #for all processes

i tak, ps manpage jest dość mylący. ( przez )

okruchy deszczu
źródło
Moje Ubuntu rozbija zmienne środowiskowe bezpośrednio w linii poleceń, nawet bez odstępu między nimi, a także obcina się do jednej linii w oknie terminala. Znalazłem ps eww $pidrozwiązuje 2. problem.
user18911,
1
@ user18911: Zmienne env mają zerowy separator znaków. Inne odpowiedzi na tej stronie pokazują sposoby ich użycia xargslub trkonwersji na nowe wiersze w celu zwiększenia czytelności. Prawdopodobnie zdałeś sobie z tego sprawę w ciągu następnych czterech lat.
Jonathan Hartley,
7
cat /proc/PID/environ

zamień PID na PID procesu, który chcesz zobaczyć. Każda informacja o uruchomionym procesie znajduje się w katalogu / proc / PID /

przykład: cat / proc / 32512 / Environment

kargig
źródło
7

Zaczerpnięte z Archlinux wiki :

Możesz utworzyć funkcję tymczasową do analizowania wartości /proc/<pid>/environ. W wierszu polecenia terminalu:

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

Następnie z pid pożądanego procesu, po prostu użyj:

envof <pid>
mwotton
źródło
6

Pod Linuksem spróbuję rzucić okiem

/proc/<pid>/environ
Joril
źródło
5

W przypadku Solaris 5.10 działa to:

pargs -e <PID>
Mykoła Nowik
źródło
5

Choć raczej słabo udokumentowana, zawartość /proc/<pid>/environbędzie zawierała tylko środowisko użyte do uruchomienia procesu.

Jeśli chcesz sprawdzić bieżący stan środowiska procesu, jednym ze sposobów jest skorzystanie z niego 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
źródło
3

A ponieważ moja praca sprawia, że ​​jestem fanem AIX, nie zapomnijmy:

ps eww [pid]

Lub, jak to nazywa strona podręcznika, „Berkeley Standards”.

Z jakiegokolwiek powodu / proc / PID / Environment nie istnieje w systemie AIX.

Corey S.
źródło
2

Jeśli chcesz utworzyć sformatowane envdane wyjściowe zmiennych środowiskowych dla dowolnego procesu (PID), możesz utworzyć wygodne penv <pid>polecenie bash (dostosowane do twojego systemu operacyjnego) i dodać je do .bashrc:

Linux dodaj to do swojego ~ / .bashrc:

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

macOS / BSD dodaj to do swojego ~ / .bashrc:

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

Solaris dodaj to do ~ / .bashrc:

penv() {
   pargs -e $1
}

Stosowanie:

$ źródło $ HOME / .bashrc
$ pgrep VBoxSVC
10268
10268 USD
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 = en_US.UTF-8
EDYTOR = vim
XDG_SESSION_ID = 106
USER = root
PWD = / root
HOME = / root
SSH_CLIENT = 1.1.1.242 53960 22
SSH_TTY = / dev / pts / 3
MAIL = / var / mail / root
TERM = xterm-256 kolor
SHELL = / bin / bash
SHLVL = 1
LOGNAME = root
DBUS_SESSION_BUS_ADDRESS = unix: ścieżka = / run / user / 0 / bus
XDG_RUNTIME_DIR = / run / user / 0
ŚCIEŻKA = / root / bin: / bin: / sbin: / usr / bin: / usr / sbin: / usr / local / bin: / usr / local / sbin :.
VBOX_LOG_FLAGS = wątek tsc
VBOX_LOG = -all + dev_vmm_backdoor.elf + dev_vmm.elf
jasne światło
źródło
0

Rozwiązanie Mac, prawdopodobnie również inne BSD mogą być czymś podobnym

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

Zmienne środowiskowe są dołączane do wiersza poleceń, usuwa to wiersz poleceń i pozostały nam tylko zmienne środowiskowe.

Nie jest idealny, ponieważ są one rozdzielone spacjami, a nie LF

Erik Martino
źródło
-1

/ proc / PID / Environment

w tym celu najpierw musimy zidentyfikować PID procesu. w tym celu możesz użyć polecenia ps

varun
źródło