Podpowłoka zaczyna się jako prawie identyczna kopia oryginalnego procesu powłoki. Pod maską powłoka wywołuje fork
wywołanie systemowe 1 , które tworzy nowy proces, którego kod i pamięć są kopiami 2 . Po utworzeniu podpowłoki istnieje bardzo niewiele różnic między nią a jej elementem nadrzędnym. W szczególności mają te same zmienne. Nawet $$
specjalna zmienna zachowuje tę samą wartość w podpowłokach: jest to identyfikator procesu oryginalnej powłoki. Podobnie $PPID
jest PID rodzica oryginalnej powłoki.
Kilka powłok zmienia kilka zmiennych w podpowłoce. Bash ustawia BASHPID
na PID procesu powłoki, który zmienia się w podpowłoce. Bash, zsh i mksh umożliwiają $RANDOM
uzyskanie różnych wartości w rodzicu i podpowłoce. Ale oprócz wbudowanych specjalnych przypadków takich jak te, wszystkie zmienne mają taką samą wartość w podpowłoce jak w oryginalnej powłoce, ten sam status eksportu, ten sam status tylko do odczytu itp. Wszystkie definicje funkcji, definicje aliasów, opcje powłoki i inne ustawienia są również dziedziczone.
Podkładka utworzona przez (…)
ma takie same deskryptory plików jak jej twórca. Niektóre inne sposoby tworzenia podpowłoki modyfikują niektóre deskryptory plików przed wykonaniem kodu użytkownika; na przykład lewa strona rury biegnie w podpowłoce 3 ze standardowym wyjściem podłączonym do rury. Podpowłoka również zaczyna się od tego samego bieżącego katalogu, tej samej maski sygnału itp. Jednym z kilku wyjątków jest to, że podpowłoki nie dziedziczą pułapek niestandardowych: ignorowane sygnały ( ) pozostają ignorowane w podpowłoce, ale inne pułapki ( SYGNAŁ ) są resetowane do domyślnej akcji 4 .trap '' SIGNAL
trap CODE
Zatem podpowłoka różni się od wykonywania skryptu. Skrypt jest osobnym programem. Ten osobny program może być przypadkowo również skryptem, który jest wykonywany przez tego samego interpretera, co rodzic, ale ten przypadek nie zapewnia osobnemu programowi żadnej szczególnej widoczności wewnętrznych danych rodzica. Nieeksportowane zmienne są danymi wewnętrznymi, więc gdy wykonywany jest interpreter skryptu powłoki potomnej , nie widzi tych zmiennych. Eksportowane zmienne, tj. Zmienne środowiskowe, są przekazywane do wykonywanych programów.
A zatem:
x=1
(echo $x)
wypisuje, 1
ponieważ podpowłoka jest replikacją powłoki, która ją zrodziła.
x=1
sh -c 'echo $x'
zdarza się, że uruchamia powłokę jako proces potomny powłoki, ale x
w drugiej linii nie ma więcej połączenia z x
drugą linią niż w
x=1
perl -le 'print $x'
lub
x=1
python -c 'print x'
1 Wyjątkiem jest ksh93
powłoka, w której rozwidlenie jest zoptymalizowane i emulowana jest większość jego skutków ubocznych.
2 Semantycznie są kopiami. Z punktu widzenia implementacji dzieje się dużo udostępniania.
3 Po prawej stronie zależy to od skorupy.
4 Jeśli to przetestujesz, zauważ, że takie rzeczy$(trap)
mogą zgłaszać pułapki oryginalnej powłoki. Zauważ też, że wiele pocisków ma błędy w narożnych skrzyniach z pułapkami. Na przykład ninjalj zauważa, że od wersji bash 4.3 bash -x -c 'trap "echo ERR at \$BASH_SUBSHELL \$BASHPID" ERR; set -E; false; echo one subshell; (false); echo two subshells; ( (false) )'
uruchamia ERR
pułapkę z zagnieżdżonej podpowłoki w przypadku „dwóch podpowłok”, ale nie ERR
pułapkę z podpowłoki pośredniej - set -E
opcja powinna propagowaćERR
pułapka na wszystkie podpowłoki, ale podpowłoka pośrednia jest zoptymalizowana, więc nie ma jej, aby uruchomić ERR
pułapkę.
x=out; (x=in; echo $x)
)echo $(x=2; echo $x)
, fragment$(x=2; echo $x)
należy rozszerzyć. Wymaga to oceny poleceniax=2; echo $x
. Rozszerzenie$x
następuje podczas tej oceny, po dokonaniu oceny częścix=2
.x
nieustawionym)echo $(echo foo >somefile)${x-$(cat somefile)}
lubecho $(echo $x),${x=1}
../file
nie jest wykonywany w podpowłoce. Zobacz także unix.stackexchange.com/q/261638 i unix.stackexchange.com/a/157962Oczywiście tak, jak mówi cała dokumentacja, nawiasowe polecenie jest uruchamiane w podpowłoce.
Podkładka dziedziczy kopię wszystkich zmiennych rodzica. Różnica polega na tym, że wszelkie zmiany wprowadzone w podpowłoce nie są również wprowadzane w obiekcie nadrzędnym.
Strona podręcznika ksh sprawia, że jest to trochę jaśniejsze niż strona bash:
man ksh
:man bash
:źródło
When a simple command other than a builtin or shell function is to be executed, it is invoked in a separate execution environment that consists of the following.
, który zawiera element:· shell variables and functions marked for export, along with variables exported for the command, passed in the environment
(z tej samejman bash
sekcji), który wyjaśnia, dlaczegoecho $x
skrypt nie drukuje nic, jeślix
nie jest eksportowany.