Linux /proc/<pid>/environ
nie aktualizuje się (jak rozumiem, plik zawiera początkowe środowisko procesu).
Jak mogę odczytać aktualne środowisko procesu ?
źródło
Linux /proc/<pid>/environ
nie aktualizuje się (jak rozumiem, plik zawiera początkowe środowisko procesu).
Jak mogę odczytać aktualne środowisko procesu ?
/proc/$pid/environ
aktualizuje się, jeśli proces zmieni własne środowisko. Ale wiele programów nie zawraca sobie głowy zmianą własnego środowiska, ponieważ jest to trochę bezcelowe: środowisko programu nie jest widoczne przez normalne kanały, tylko przez /proc
i ps
, i nawet nie każdy wariant unixa ma taką funkcję, więc aplikacje nie polegają na tym.
Jeśli chodzi o jądro, środowisko pojawia się tylko jako argument execve
wywołania systemowego uruchamiającego program. Linux udostępnia obszar pamięci /proc
, a niektóre programy aktualizują ten obszar, a inne nie. W szczególności nie sądzę, aby jakakolwiek powłoka aktualizowała ten obszar. Ponieważ obszar ma stały rozmiar, dodanie nowych zmiennych lub zmiana długości wartości byłaby niemożliwa.
PATH=foo
w powłoce, nie oznacza, że powłoka się zmieni*envp
. W niektórych powłokach aktualizuje to tylko wewnętrzną strukturę danych i aktualizuje się zewnętrzny kod wykonania programu*envp
. Spójrz na przykładassign_in_env
wvariables.c
źródle bash.fork
to libc wykonujesys_fork
połączenie, używając środowiska przydzielonego do sterty dla procesu potomnego.argv
są częstsze, ale oba istnieją).Możesz odczytać początkowe środowisko procesu z
/proc/<pid>/environ
.Jeśli proces zmienia swoje środowisko, to aby odczytać środowisko, musisz mieć tabelę symboli dla procesu i użyć
ptrace
wywołania systemowego (na przykład za pomocągdb
), aby odczytać środowisko zechar **__environ
zmiennej globalnej . Nie ma innego sposobu uzyskania wartości dowolnej zmiennej z uruchomionego procesu Linux.To jest odpowiedź. Teraz kilka notatek.
Powyższe zakłada, że proces jest zgodny z POSIX, co oznacza, że proces zarządza swoim środowiskiem przy użyciu zmiennej globalnej
char **__environ
określonej w Spec Spec .Początkowe środowisko dla procesu jest przekazywane do procesu w buforze o stałej długości na stosie procesu. (Zwykłym mechanizmem, który to robi
linux//fs/exec.c:do_execve_common(...)
.) Ponieważ rozmiar bufora jest obliczany jako nie większy niż rozmiar wymagany dla środowiska początkowego, nie można dodawać nowych zmiennych bez usuwania istniejących zmiennych lub niszczenia stosu. Tak więc każdy rozsądny schemat pozwalający na zmiany w środowisku procesu wykorzystywałby stertę, w której pamięć o dowolnych rozmiarach może być przydzielana i zwalniana, co dokładnie robi dla ciebie GNUlibc
(glibc
).Jeśli proces używa
glibc
, to jest zgodny z POSIX, a__environ
deklaracja wglibc//posix/environ.c
Glibc inicjuje__environ
wskaźnikiem do pamięci, żemalloc
pochodzi ze sterty procesu, a następnie kopiuje środowisko początkowe ze stosu do tego obszaru sterty. Za każdym razem proces wykorzystujesetenv
funkcję,glibc
wymaga sięrealloc
, aby dostosować rozmiar obszaru, który__environ
wskazuje, aby pomieścić nową wartość lub zmienną. (Możesz pobrać kod źródłowy glibc za pomocągit clone git://sourceware.org/git/glibc.git glibc
). Aby naprawdę zrozumieć mechanizm, musisz także przeczytać kod Hurd whurd//init/init.c:frob_kernel_process()
(git clone git: //git.sv.gnu.org/hurd/hurd.git hurd).Teraz, jeśli nowy proces jest tylko
fork
edytowany, bez późniejszegoexec
nadpisywania stosu, to magia kopiowania argumentów i środowiska jest wykonywanalinux//kernel/fork.c:do_fork(...)
, gdziecopy_process
rutynowe wywołania,dup_task_struct
które przydzielają stos nowego procesu przez wywołaniealloc_thread_info_node
, które wywołujesetup_thread_stack
(linux//include/linux/sched.h
) dla nowego procesu za pomocąalloc_thread_info_node
.Wreszcie
__environ
konwencja POSIX to konwencja przestrzeni użytkownika . Nie ma połączenia z niczym w jądrze Linuksa. Możesz napisać program przestrzeni użytkownika bez użycia globalnego iglibc
bez niego,__environ
a następnie zarządzać zmiennymi środowiskowymi w dowolny sposób. Nikt cię nie aresztuje za to, ale będziesz musiał napisać własne funkcje zarządzania środowiskiem (setenv
/getenv
) i własne opakowaniasys_exec
i jest prawdopodobne, że nikt nie będzie w stanie zgadnąć, gdzie wprowadzasz zmiany w swoim środowisku.źródło
/proc/[pid]/
wydaje się mieć dziwne kodowanie (ktoś inny może wiedzieć, co i dlaczego). Dla mnie po prostucat environ
wydrukowałbym zmienne środowiskowe w naprawdę trudnym do odczytania formacie.cat environ | strings
rozwiązałem to dla mnie.Jest aktualizowany w miarę, jak proces nabywa / usuwa swoje zmienne środowiskowe. Czy masz odniesienie, które stwierdza, że
environ
plik nie jest aktualizowany dla procesu w katalogu procesu w systemie plików / proc?lub
lub
Powyżej wydrukuje zmienne środowiskowe procesu w
ps
formacie wyjściowym, przetwarzanie tekstu (parsowanie / filtrowanie) jest wymagane, aby zobaczyć zmienne środowiskowe jako listę.Solaris (nie pytany, ale w celach informacyjnych opublikuję tutaj):
lub
EDYCJA: / proc / pid / Environment nie jest aktualizowany! Poprawiono mnie. Proces weryfikacji jest poniżej. Jednak elementy potomne, z których rozwidla się proces, dziedziczą zmienną środowiskową procesu i jest ona widoczna w odpowiednim pliku / proc / self / environment. (Użyj ciągów)
With in the shell: tutaj xargs jest procesem potomnym i dlatego dziedziczy zmienną środowiskową, a także odzwierciedla w swoim
/proc/self/environ
pliku.Sprawdzanie go z innej sesji, w której terminal / sesja nie jest procesem potomnym powłoki, w której ustawiona jest zmienna środowiskowa.
Weryfikacja z innego terminala / sesji na tym samym hoście:
terminal1: Zauważ, że printenv jest rozwidlony i jest potomnym procesem bash, a zatem czyta własny plik środowiska.
terminal2: na tym samym hoście - nie uruchamiaj go w tej samej powłoce, w której ustawiono powyższą zmienną, uruchom terminal osobno.
źródło
export foo=bar
w sesji jednego basha (pid xxxx), potem robięcat /proc/xxxx/environ | tr \\0 \\n
w sesji innego basha i nie widzęfoo
.gdb
do pid, ale wciąż nie ma tam odniesienia. Blok zmiennych środowiskowych w pamięci zostaje ponownie przydzielony za każdym razem, gdy zachodzi zmiana i nie odzwierciedla pliku środowiska własnego procesu w systemie plików proc, ale pozwala na dziedziczenie przez proces potomny. Oznacza to, że łatwiej będzie poznać wewnętrzne szczegóły, kiedy nastąpi rozwidlenie, w jaki sposób proces potomny pobiera zmienne środowiskowe w takiej postaci, w jakiej są.Cóż, poniższe informacje nie są powiązane z prawdziwymi intencjami autora, ale jeśli naprawdę chcesz „CZYTAĆ”
/proc/<pid>/environ
, możesz spróbowaćco jest lepsze niż
cat
to.źródło
strings
. Nie komplikuj.xargs --null
.tr '\0' '\n' < /proc/$$/environ | ...