Jaka jest dokładna różnica między „podpowłoką” a „procesem potomnym”?


16

Zgodnie z tym i tym , podpowłoka jest uruchamiana za pomocą nawiasu (…).

( echo "Hello" )

Zgodnie z tym , to i to , proces jest rozwidlany, gdy polecenie jest uruchamiane za pomocą&

echo "Hello" &

Specyfikacja Posix używa słowa subshellna tej stronie, ale go nie definiuje, a także na tej samej stronie, nie definiuje „procesu potomnego” .

Oba używają fork()funkcji jądra , prawda?

Jaka jest dokładna różnica nazywania niektórych rozwidleń „podpowłoką”, a niektórych innych - „procesem potomnym”.


Nie jest jasne, dlaczego łączysz uzasadnienie POSIX : Definicje podstawowe zamiast samych definicji podstawowych : 3.93 Proces potomny „Nowy proces utworzony (przez fork (), posix_spawn () lub ...) przez dany proces” ; 3.376 Podpowłoka „Środowisko wykonywania powłoki, odróżnione od głównego lub bieżącego środowiska wykonywania powłoki” . Więc nie ma tego samego rodzaju rzeczy. Czy to jest to rozróżnienie, którego szukasz?
fra-san

@ fra-san A child processmoże mieć inne środowisko niż main: jak w ( LANG=C eval 'echo "$LANG"' ). Czy ten proces potomny (w nawiasie) jest również podpowłoką (inne środowisko)?
Izaak

Wyrażenie in ( )jest z definicji podpowłoką z własnym środowiskiem wykonawczym. Chodzi mi o to, że podpowłoka nie musi być implementowana jako proces potomny (jak wskazuje Stéphane w swojej odpowiedzi z przykładem ksh93). Wygląda na to powłoki w tle , a proces potomny nie muszą być obydwa wyniki fork()wezwania; dlatego szukanie różnicy między dwoma rodzajami widelca nie wydaje mi się właściwym punktem widzenia. Właśnie dlatego starałem się lepiej zrozumieć twoje pytanie.
fra-san

Ach, teraz widzę, że strona tldp, do której prowadzisz link, faktycznie mówi, że podpowłoka jest procesem potomnym. Moim zdaniem ta definicja może być mylącym uproszczeniem.
fra-san

Odpowiedzi:


15

W terminologii POSIX środowisko podpowłoki jest powiązane z pojęciem środowiska wykonawczego powłoki .

Środowisko podpowłoki jest oddzielnym środowiskiem wykonywania powłoki utworzonym jako duplikat środowiska nadrzędnego. To środowisko wykonawcze obejmuje takie rzeczy, jak otwarte pliki, umask, katalog roboczy, zmienne / funkcje / aliasy powłoki ...

Zmiany w tym środowisku podpowłoki nie wpływają na środowisko nadrzędne.

Tradycyjnie w powłoce Bourne'a lub ksh88, na której oparta jest specyfikacja POSIX, zostało to zrobione przez rozwarcie procesu potomnego.

Obszary, w których POSIX wymaga lub pozwala na uruchamianie komend w środowisku podpowłoki, to te, w których tradycyjnie ksh88 rozwidlał proces powłoki potomnej.

Nie zmusza to jednak implementacji do użycia do tego procesu potomnego.

Powłoka może zamiast tego wybrać wdrożenie oddzielnego środowiska wykonawczego w dowolny sposób.

Na przykład, ksh93 robi to poprzez zapisywanie atrybutów nadrzędnego środowiska wykonawczego i przywracanie ich po zakończeniu środowiska podpowłoki w kontekstach, w których można uniknąć rozwidlenia (jako optymalizacja, ponieważ rozwidlanie jest dość kosztowne w większości systemów).

Na przykład w:

cd /foo; pwd
(cd /bar; pwd)
pwd

POSIX wymaga cd /foodziałania w osobnym środowisku i wypisywania czegoś takiego:

/foo
/bar
/foo

Nie wymaga działania w osobnym procesie. Na przykład, jeśli stdout staje się zepsutą rurą, pwduruchom w środowisku podpowłoki może bardzo dobrze, że SIGPIPE zostanie wysłany do jedynego procesu powłoki.

Większość powłok, w tym bash, implementuje go, oceniając kod wewnątrz (...)procesu potomnego (podczas gdy proces macierzysty czeka na jego zakończenie), ale ksh93 zamiast tego uruchomi kod wewnątrz (...), wszystko w tym samym procesie:

  • pamiętaj, że jest w środowisku podpowłoki.
  • następnie cdzapisz poprzedni katalog roboczy (zwykle na deskryptorze pliku otwartym za pomocą O_CLOEXEC), zapisz wartość zmiennych OLDPWD, PWD i wszystko, co cdmoże zmodyfikować, a następnie wykonajchdir("/bar")
  • po powrocie z podpowłoki przywracany jest bieżący katalog roboczy ( fchdir()na tym zapisanym fd) i wszystko inne, co podpowłoka mogła zmodyfikować.

Istnieją konteksty, w których nie można uniknąć procesu potomnego. ksh93 nie rozwidla się:

  • var=$(subshell)
  • (subshell)

Ale robi to

  • { subshell; } &
  • { subshell; } | other command

Oznacza to, że przypadki muszą przebiegać w osobnych procesach, aby mogły działać równolegle.

Optymalizacje ksh93 idą dalej. Na przykład podczas pobytu w

var=$(pwd)

większość powłok rozwidliłaby proces, gdyby dziecko uruchomiło pwdpolecenie ze stdout przekierowanym do potoku, pwdzapisało bieżący katalog roboczy do tego potoku, a proces nadrzędny odczytałby wynik na drugim końcu potoku, ksh93wirtualizuje to wszystko wymagające widelca ani rury. Widelec i potok byłyby używane tylko dla poleceń niewbudowanych.

Zauważ, że istnieją inne konteksty niż podpowłoki, dla których powłoki rozwidlają proces potomny. Na przykład, aby uruchomić polecenie zapisane w osobnym pliku wykonywalnym (który nie jest skryptem przeznaczonym dla tego samego interpretera powłoki), powłoka musiałaby rozwidlić proces, aby uruchomić w nim to polecenie, ponieważ inaczej nie byłby w stanie uruchomić więcej poleceń po powrocie tego polecenia.

W:

/bin/echo "$((n += 1))"

To nie jest podpowłoka, polecenie zostanie ocenione w bieżącym środowisku wykonywania powłoki, nzmienna bieżącego środowiska wykonywania powłoki zostanie zwiększona, ale powłoka rozwinie proces potomny w celu wykonania tego /bin/echopolecenia z rozszerzeniem $((n += 1))as argument .

Wiele powłok implementuje optymalizację w taki sposób, że nie rozwidla procesu potomnego, aby uruchomić to polecenie zewnętrzne, jeśli jest to ostatnie polecenie skryptu lub podpowłoki (dla tych podpowłok, które są zaimplementowane jako procesy potomne). ( bashrobi to jednak tylko wtedy, gdy to polecenie jest jedynym poleceniem podpowłoki).

Oznacza to, że w przypadku tych powłok, jeśli ostatnie polecenie w podpowłoce jest poleceniem zewnętrznym, podpowłoka nie powoduje odrodzenia dodatkowego procesu. Jeśli porównasz:

a=1; /bin/echo "$a"; a=2; /bin/echo "$a"

z

a=1; /bin/echo "$a"; (a=2; /bin/echo "$a")

powstanie taka sama liczba procesów, tylko w drugim przypadku drugie rozwidlenie jest zrobione wcześniej, aby a=2było uruchamiane w środowisku podpowłoki.


1

Subshell

Powłoka potomna jest również nazywana podpowłoką. Podpowłokę można utworzyć z powłoki nadrzędnej i z innej powłoki. Podshell można utworzyć za pomocą:

1. Lista procesów

Lista procesów to grupowanie poleceń ujęte w nawiasy. Przykład:

( pwd ; (echo $BASH_SUBSHELL)) 

Spowoduje to wydrukowanie bieżącego katalogu roboczego i liczby spawnowanych powłok. UWAGA Wywołanie podpowłoki jest drogie.

2. Koproces

Odradza podpowłokę w trybie tła i wykonuje polecenie w tej podpowłoce.

coproc sleep 10

Jeśli wpiszesz jobspolecenie

[1]+  Running                 coproc COPROC sleep 10 &

zobaczysz sen jako proces działający w tle.

Rozwidlenie procesu potomnego

Proces potomny w przetwarzaniu jest procesem utworzonym przez inny proces. Za każdym razem, gdy wykonywane jest polecenie zewnętrzne, tworzony jest proces potomny. To działanie nazywa się rozwidleniem.

$ps -f
UID        PID  PPID  C STIME TTY          TIME CMD  
umcr7     3647  3638  0 13:54 pts/0    00:00:00 bash
umcr7     3749  3647  0 13:59 pts/0    00:00:00 ps -f

Podobnie jak ps -fpolecenie zewnętrzne (tj. Polecenie zewnętrzne, czasami nazywane poleceniem systemu plików, to program, który istnieje poza powłoką bash). Spowoduje to utworzenie procesu potomnego z nadrzędnym identyfikatorem powłoki bash, z którego jest wykonywany.


0

Zarówno (podpowłoka, jak i powłoka podrzędna) są osobnym procesem niż powłoka nadrzędna (oba są potomkami powłoki nadrzędnej). Oznacza to, że mają różne PID. I oba zaczynają się od rozwidlenia (kopii) powłoki macierzystej.

Podpowłoka jest kopią powłoki nadrzędnej, w której zmienne, funkcje, flagi i wszystko jest dostępne tak, jak było w powłoce nadrzędnej. Modyfikacje takich wartości nie wpływają na element nadrzędny.

Powłoka podrzędna zaczyna się jako rozwidlenie, ale resetuje się do domyślnych wartości powłoki podanych przez konfiguracje początkowe. Staje się procesem używanym do wykonania jakiegoś kodu (powłoki lub polecenia).

Podkładka może uzyskiwać dostęp do wartości zmiennych:

$ x=123; ( echo "$x")
123

Powłoka podrzędna nie mogła (nieeksportowane zmienne):

$ x=234; sh -c 'echo "x=$x"'
x=
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.