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=1
set -a
:Řekne shellu, aby vložil jakýkoli název, který se nastaví do prostředí. Jako když vložíteexport
před každým úkolem. Užitečné pro.env
soubory, 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říkazenv
vá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á.