it-swarm-eu.dev

Jak číst proměnné prostředí procesu

Linux je /proc/<pid>/environ se neaktualizuje (jak tomu rozumím, soubor obsahuje počáteční prostředí procesu).

Jak si mohu přečíst prostředí aktuální procesu?

45
user14284

/proc/$pid/environ aktualizuje se, pokud proces změní své vlastní prostředí. Mnoho programů se však neobtěžuje měnit své vlastní prostředí, protože je to trochu zbytečné: prostředí programu není viditelné běžnými kanály, pouze prostřednictvím /proc a ps, a dokonce ne každá unixová varianta má tento druh funkce, takže se na ni aplikace nespoléhají.

Pokud jde o jádro, prostředí se objeví pouze jako argument systémového volání execve , které spustí program. Linux odhaluje oblast v paměti prostřednictvím /proc a některé programy tuto oblast aktualizují, zatímco jiné ne. Zejména si nemyslím, že žádný Shell tuto oblast aktualizuje. Protože oblast má pevnou velikost, nebylo by možné přidat nové proměnné nebo změnit délku hodnoty.

Můžete si přečíst počáteční prostředí procesu z /proc/<pid>/environ.

Pokud se proces změní jeho prostředí, pak, abyste mohli číst prostředí, musíte mít tabulku symbolů pro proces a použít ptrace systémové volání (například pomocí gdb) pro čtení prostředí z globální proměnné char **__environ. Neexistuje žádný jiný způsob, jak získat hodnotu jakékoli proměnné z běžícího procesu v systému Linux.

To je odpověď. Nyní pro pár poznámek.

Výše uvedené předpokládá, že proces je kompatibilní s POSIX, což znamená, že proces řídí své prostředí pomocí globální proměnné char **__environ, Jak je uvedeno v Ref Spec .

Počáteční prostředí pro proces se předává procesu ve vyrovnávací paměti s pevnou délkou na zásobníku procesu. (Obvyklý mechanismus, který to dělá, je linux//fs/exec.c:do_execve_common(...).) Protože je velikost vyrovnávací paměti vypočítána tak, aby nepřesahovala velikost požadovanou pro počáteční prostředí, nemůžete přidat nové proměnné bez vymazání existujících proměnných nebo rozbití zásobníku. Jakékoli rozumné schéma umožňující změny v prostředí procesu by tedy použilo haldu, kde lze alokovat a uvolnit paměť v libovolných velikostech, což je přesně to, co GNU libc (glibc) pro vás.

Pokud proces používá glibc, pak je kompatibilní s POSIX, přičemž __environ Je deklarováno v glibc//posix/environ.c Glibc inicializuje __environ Ukazatelem na paměť, že mallocs z haldy procesu a poté zkopíruje počáteční prostředí ze zásobníku do této oblasti haldy. Pokaždé, když proces používá funkci setenv, provede glibc nastavení realloc k úpravě velikosti oblasti, na kterou odkazuje __environ, Aby se přizpůsobila nové hodnotě nebo proměnná. (Zdrojový kód glibc si můžete stáhnout pomocí git clone git://sourceware.org/git/glibc.git glibc). Abychom skutečně pochopili mechanismus, musíte si také přečíst Hurdův kód v hurd//init/init.c:frob_kernel_process() (git clone git: //git.sv.gnu.org/hurd/hurd.git hurd).

Nyní, pokud je nový proces pouze forked, aniž by následný exec přepsal zásobník, pak se kouzlo kouzla a prostředí kopíruje v linux//kernel/fork.c:do_fork(...), kde copy_process Rutinní volání dup_task_struct, Která přiděluje zásobník nového procesu voláním alloc_thread_info_node, Který volá setup_thread_stack (linux//include/linux/sched.h) Pro nový proces pomocí alloc_thread_info_node.

Konečně, konvence POSIX __environ Je konvencí user-space. V jádru systému Linux nemá nic společného. Můžete psát program userpace bez použití glibc a bez globálního __environ A potom spravovat proměnné prostředí, jak chcete. Nikdo vás za to nezatkne, ale budete muset napsat vlastní funkce správy prostředí (setenv/getenv) a své vlastní obálky pro sys_exec A je pravděpodobné, že nikdo nebude schopen hádat, kam umístíte změny do svého prostředí.

41

Aktualizuje se, jakmile proces získá/odstraní své proměnné prostředí. Máte odkaz, který uvádí, že soubor environ není aktualizován pro proces v jeho procesním adresáři pod souborovým systémem/proc?

xargs --null --max-args=1 echo < /proc/self/environ

nebo

xargs --null --max-args=1 echo < /proc/<pid>/environ

nebo

ps e -p <pid>

Výše uvedené bude tisknout proměnné prostředí procesu ve výstupním formátu ps, textové zpracování (analyzování/filtrování) je vyžadováno, aby se proměnné prostředí zobrazily jako seznam.

Solaris (nepožádán, ale pro informaci budu psát zde):

/usr/ucb/ps -wwwe <pid>

nebo

pargs -e <pid> 

ÚPRAVA:/proc/pid/environment není aktualizována! Opravuji to. Proces ověření je níže. Děti, od kterých je proces viditelný, zdědí proměnnou procesního prostředí a je vidět v jejich příslušném souboru/proc/self/environment. (Použijte řetězce)

With in Shell: here xargs je podřízený proces, a proto zdědí proměnnou prostředí a odráží se také v jeho /proc/self/environ soubor.

[[email protected] t]$ printenv  | grep MASK
[[email protected] t]$ export MASK=NIKHIL
[[email protected] t]$ printenv  | grep MASK
MASK=NIKHIL
[[email protected] t]$ xargs --null --max-args=1 echo < /proc/self/environ  | grep MASK
MASK=NIKHIL
[[email protected] t]$ unset MASK
[[email protected] t]$ printenv  | grep MASK
[[email protected] t]$ xargs --null --max-args=1 echo < /proc/self/environ  | grep MASK
[[email protected] t]$

Kontrola z jiné relace, kde terminál/relace není podřízeným procesem prostředí, kde je nastavena proměnná prostředí.

Ověření z jiného terminálu/relace na stejném hostiteli:

terminal1:: Všimněte si, že printenv je vidlice a je podřízeným procesem bash, a proto čte svůj vlastní environmentální soubor.

[[email protected] t]$ echo $$
2610
[[email protected] t]$ export SPIDEY=NIKHIL
[[email protected] t]$ printenv | grep SPIDEY
SPIDEY=NIKHIL
[[email protected] t]$ 

terminal2: na stejném hostiteli - nespouštějte jej ve stejném prostředí, ve kterém byla nastavena výše uvedená proměnná, spusťte terminál samostatně.

[[email protected] ~]$ echo $$
4436
[[email protected] ~]$ xargs --null --max-args=1 echo < /proc/self/environ | grep -i spidey
[[email protected] ~]$ strings -f /proc/2610/environ | grep -i spidey
[[email protected] ~]$ xargs --null --max-args=1 echo < /proc/2610/environ | grep -i spidey
[[email protected] ~]$ 
22
Nikhil Mulley

Následující text nesouvisí se skutečnými úmysly autora, ale pokud opravdu chcete „PŘEČTĚT“ /proc/<pid>/environ, můžete zkusit

strings /proc/<pid>/environ

což je lepší než cat it.

8
fibonacci