GNU/Linux >> Znalost Linux >  >> Linux

Jsou proměnné mimo prostředí předány do podslupky vyvolány substitucí příkazů?

Bash manuál říká:

Náhrada příkazů, příkazy seskupené se závorkami a asynchronní příkazy jsou vyvolány v prostředí podshellu, které je duplikátem prostředí shellu,
kromě toho, že pasti zachycené shellem jsou resetovány na hodnoty, které shell zdědil od svého rodiče na vyvolání.

V tomto příkladu b není proměnná prostředí, takže b neexistuje v subshell vytvořeném substitucí příkazu. Tak proč je c přiřazena hodnota b substitucí příkazů? Je to proto, že k rozšíření parametru dochází pro $b v procesu shellu před vytvořením subshell ke spuštění echo 1 ?

$ b=1
$ c=$(echo $b)
$ echo $c
1

Přijatá odpověď:

Ne, subshell byl vytvořen jako první.

Prostředí spouštění shellu obsahuje parametry shellu nastavené přiřazením proměnných a proměnnými prostředí. Prostředí subshell bylo vytvořeno duplikací prostředí shellu, takže obsahuje všechny proměnné aktuálního prostředí shellu.

Viz příklad:

$ b=1
$ c=$(b=2; echo "$b")
$ echo "$c"
2

Výstup je 2 místo 1 .

Prostředí subshell vytvořené substitucí příkazů se liší od prostředí shellu vytvořeného voláním spustitelného souboru shellu.

Když zavoláte shell jako:

$ bash -c :

aktuální shell použil execve() k vytvoření nového procesu shellu, něco jako:

execve("/bin/bash", ["bash", "-c", ":"], [/* 64 vars */]) = 0

poslední argument předaný do execve obsahuje všechny proměnné prostředí.

To je důvod, proč musíte exportovat proměnné a vložit je do proměnných prostředí, které budou zahrnuty do následně provedených příkazů:

$ a=; export a
$ strace -e execve bash -c :
execve("/bin/bash", ["bash", "-c", ":"], [/* 65 vars */]) = 0
+++ exited with 0 +++

Všimněte si, že proměnné prostředí se mění z 64 na 65. A proměnné, které nejsou exportovány, nebudou předány do nového prostředí shellu:

$ a=; b=; export a
$ strace -e execve bash -c :
execve("/bin/bash", ["bash", "-c", ":"], [/* 65 vars */]) = 0
+++ exited with 0 +++

Všimněte si, že proměnné prostředí jsou stále 65.

Při substituci příkazů shell použil fork() k vytvoření nového procesu shellu, který pouze zkopíroval aktuální prostředí shellu – které obsahuje jak sadu proměnných, tak proměnné prostředí.


Linux
  1. Jak přiřadit výstup příkazu proměnné shellu?

  2. Jaký je rozsah exportovaných proměnných shellu Unix?

  3. Skrýt výstup příkazu shellu pouze při úspěchu?

  1. Existují konvence pojmenování proměnných ve skriptech Shell?

  2. Pointa externího příkazu `cd`?

  3. Jaký je nejlepší způsob nastavení proměnných prostředí podle distro/shell agnostického prostředí?

  1. Rozdíl v použití mezi proměnnými shellu a proměnnými prostředí?

  2. Opravdu vkládají závorky příkaz do podslupky?

  3. Jaký je rozdíl mezi získáním výstupu příkazu pomocí `command` a $(command) v Shell?