Zde jsem četl, že účel export v shellu je zpřístupnit proměnnou podprocesům spouštěným z shellu.
Zde a zde jsem však také četl, že „Procesy dědí své prostředí od svého rodiče (proces, který je spustil).“
Pokud je to tento případ, proč potřebujeme export ? Co mi chybí?
Nejsou proměnné prostředí ve výchozím nastavení součástí prostředí? Jaký je rozdíl?
Přijatá odpověď:
Váš předpoklad je, že proměnné shellu jsou v prostředí . Toto je nesprávné. export příkaz je to, co definuje jméno, které má být vůbec v prostředí. Tedy:
a=1 b=2
export b
výsledkem je aktuální shell s vědomím, že $a expanduje na 1 a $b až 2, ale podprocesy nebudou vědět nic o a protože není součástí prostředí (ani v aktuálním prostředí).
Některé užitečné nástroje:
set:Užitečné pro zobrazení parametrů aktuálního shellu, exportováno-nebo-neset -k:Nastaví přiřazené argumenty v prostředí. Zvažtef() { set -k; env; }; f a=1set -a:Řekne shellu, aby vložil jakýkoli název, který se nastaví do prostředí. Jako když vložíteexportpřed každým úkolem. Užitečné pro.envsoubory, jako vset -a; . .env; set +a.export:Řekne shellu, aby vložil název do prostředí. Export a přiřazení jsou dvě zcela odlišné operace.env:Jako externí příkazenvvám může říct pouze o zděděných prostředí, takže je užitečné pro kontrolu zdravého rozumu.env -i:Užitečné pro vyčištění prostředí před spuštěním dílčího procesu.
Alternativy k export :
name=val command# Assignment before command exportuje tento název do příkazu.declare/local -x name# Exportuje jméno, zvláště užitečné ve funkcích shellu, když se chcete vyhnout vystavení názvu mimo rozsah.set -a# Exportuje každý následující úkol.
Motivace
Proč tedy shelly potřebují mít své vlastní proměnné a jiné prostředí? Jsem si jistý, že existují nějaké historické důvody, ale myslím, že hlavním důvodem je rozsah. Prostředí je pro podprocesy, ale existuje mnoho operací, které můžete provádět v shellu bez rozvětvení podprocesu. Předpokládejme, že zacyklíte:
for i in {0..50}; do
somecommand
done
Proč plýtvat pamětí pro somecommand zahrnutím i , čímž je jeho prostředí větší, než je potřeba? Co když název proměnné, který jste vybrali v shellu, náhodou znamená pro program něco nezamýšleného? (Mezi mé osobní oblíbené patří DEBUG a VERBOSE . Tato jména jsou používána všude a jen zřídka jsou dostatečně jmenné prostory.)
Co je to prostředí, když ne shell?
Někdy, abyste pochopili chování Unixu, musíte se podívat na syscalls, základní API pro interakci s jádrem a OS. Zde se díváme na exec rodina volání, což je to, co shell používá, když vytváří podproces. Zde je citát z manuálové stránky pro exec(3) (důraz můj):
execle()aexecvpe()funkce umožňují volajícímu specifikovat prostředí spouštěného programu pomocí argumentu envp. Argument envp je pole ukazatelů na řetězce ukončené nulou a musí být ukončeno ukazatelem NULL. Ostatní funkce přebírají prostředí pro nový obraz procesu z prostředí externí proměnné ve volajícím procesu.
Takže psaní export somename v shellu by bylo ekvivalentní zkopírování názvu do globálního slovníku environ v C. Ale přiřazení somename bez exportu by to bylo jako přiřadit to v C, bez kopírování do environ proměnná.