GNU/Linux >> Znalost Linux >  >> Linux

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

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 pro čtení 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ího char **__environ variabilní. Neexistuje žádný jiný způsob, jak získat hodnotu jakékoli proměnné ze spuštěného linuxového procesu.

To je odpověď. Nyní několik poznámek.

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

Počáteční prostředí pro proces je předáno procesu ve vyrovnávací paměti s pevnou délkou v zásobníku procesu. (Obvyklý mechanismus, který to dělá, je linux//fs/exec.c:do_execve_common(...) .) Vzhledem k tomu, že velikost vyrovnávací paměti je vypočítána tak, aby nebyla větší než velikost požadovaná pro počáteční prostředí, nemůžete přidávat 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 využívalo haldu, kde lze alokovat a uvolnit paměť v libovolných velikostech, což je přesně to, co GNU libc (glibc ) dělá pro vás.

Pokud proces používá glibc , pak je kompatibilní s POSIX s __environ deklarován v glibc//posix/environ.c Glibc inicializuje __environ s ukazatelem do paměti, že malloc s z haldy procesu, poté zkopíruje počáteční prostředí ze zásobníku do této oblasti haldy. Pokaždé, když proces používá setenv funkce, glibc udělá realloc upravit velikost oblasti, která __environ ukazuje na pro přizpůsobení nové hodnotě nebo proměnné. (Zdrojový kód glibc si můžete stáhnout pomocí git clone git://sourceware.org/git/glibc.git glibc ). Abyste skutečně pochopili mechanismus, budete si muset přečíst také Hurd kód v hurd//init/init.c:frob_kernel_process() (klon git git://git.sv.gnu.org/hurd/hurd.git hurd).

Nyní, pokud je nový proces pouze fork ed, bez následných exec přepsáním zásobníku, pak se kouzlo zkopírování argumentů a prostředí provede v linux//kernel/fork.c:do_fork(...) , kde copy_process rutinní volání dup_task_struct který alokuje zásobník nového procesu voláním alloc_thread_info_node , který se nazývá setup_thread_stack (linux//include/linux/sched.h ) pro nový proces pomocí alloc_thread_info_node .

Nakonec POSIX __environ konvence je uživatelský prostor konvence. Nemá žádnou souvislost s ničím v linuxovém jádře. Program v uživatelském prostoru můžete napsat bez použití glibc a bez __environ globální a pak spravujte proměnné prostředí, jak chcete. Nikdo vás za to nezatkne, ale budete si muset napsat své vlastní funkce správy prostředí (setenv /getenv ) a vaše vlastní obálky pro sys_exec a je pravděpodobné, že nikdo nebude schopen uhodnout, kam jste změny ve svém prostředí umístili.


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

Pokud jde o jádro, prostředí se objevuje pouze jako argument execve systémové volání, které spustí program. Linux zpřístupňuje 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 aktualizuje tuto oblast. Protože oblast má pevnou velikost, nebylo by možné přidávat nové proměnné nebo měnit délku hodnoty.


Aktualizuje se, když proces získá/vymaže své proměnné prostředí. Máte odkaz, který uvádí environ soubor není aktualizován pro proces v jeho adresáři procesu pod /proc filesystem?

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é vypíše proměnné prostředí procesu v ps výstupní formát, k zobrazení proměnných prostředí jako seznamu je vyžadováno zpracování textu (analýza/filtrování).

Solaris (není dotazován, ale pro referenci zde zveřejním):

/usr/ucb/ps -wwwe <pid>

nebo

pargs -e <pid> 

UPRAVIT: /proc/pid/environ není aktualizován! stojím opravený. Ověřovací proces je níže. Nicméně děti, od kterých je proces rozvětvený, zdědí proměnnou prostředí procesu a je viditelná v jejich příslušném souboru /proc/self/environ. (Použijte řetězce)

S v shellu:zde je xargs podřízený proces, a proto zdědí proměnnou prostředí a také se odráží ve svém /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 shellu, kde je nastavena proměnná prostředí.

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

terminál1: :Všimněte si, že printenv je rozvětvený a je podřízeným procesem bash, a proto čte svůj vlastní soubor environ.

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

terminál2: na stejném hostiteli – nespouštějte jej ve stejném prostředí, kde 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] ~]$ 

Linux
  1. Jak mohu přimět R číst mé proměnné prostředí?

  2. Jak nastavit proměnné prostředí Linuxu pomocí Ansible

  3. Jak vytisknout zjevně skryté proměnné prostředí?

  1. Jak předávat proměnné prostředí do kontejnerů Docker

  2. Jak nastavit, vypsat a odebrat proměnné prostředí v Linuxu

  3. Jsou proměnné prostředí viditelné pro neprivilegované uživatele v systému Linux?

  1. Jak dáte su aktuální proměnné uživatelského prostředí

  2. Jak zrušit nastavení mnoha proměnných prostředí

  3. Proměnné prostředí běžícího procesu na Unixu?