podpowłoka nie jest tworzona, jeśli uruchamiasz polecenia bez ścieżki?


Czytam książkę "

Linux Command Line and the Shell Scripting Bible

"Trzecie wydanie. Na stronie 279 cytuję:

„Zastępowanie poleceń tworzy tak zwane
         subshell
aby uruchomić podane polecenie. Podpowłoka to oddzielna powłoka potomna utworzona z powłoki, w której wykonywany jest skrypt. Z tego powodu żadne zmienne utworzone w skrypcie nie są dostępne dla polecenia podpowłoki.
Podpowłoki są również tworzone, jeśli uruchomisz polecenie z wiersza poleceń za pomocą
         ./
ścieżka, ale nie zostaną utworzone, jeśli po prostu uruchomisz polecenie bez ścieżki. "

Ostatnie zdanie mnie dezorientuje. Przetestowałem prosty skrypt, który eksportuje niektóre zmienne; zmienne nie będą istniały po istnieniu skryptu, jednak skrypt jest wywoływany z
       ./
path lub umieść skrypt
/usr/bin
i biegnij bez ścieżki. Wydaje mi się, że nie ma znaczenia, jak jest nazywany w stosunku do podpowłoki.
Co mnie ominęło?
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

„Zastępowanie poleceń tworzy tak zwaną podpowłokę do wykonywania polecenia zagnieżdżonego. Podpowłoka to oddzielna powłoka potomna utworzona z powłoki, która uruchamia skrypt.

Mowa o takich konstrukcjach jak:
echo "$(date) `uname -r`"

W tym przykładzie wywołuję dwie podpowłoki przy użyciu dwóch różnych obsługiwanych notacji podpowłoki. Uruchamia się pierwsza podpowłoka
         date
polecenie, a druga podpowłoka zostanie uruchomiona
         uname
zespół. W
         echo
Polecenie jest wykonywane przez oryginalną powłokę po zakończeniu działania obu podpowłok.

Z tego powodu żadne zmienne utworzone w skrypcie nie są dostępne dla polecenia podpowłoki.

Tutaj autor cofnął się. Zmienne utworzone przed wywołaniem podpowłoki są dostępne dla podpowłoki. Zmienne utworzone wewnątrz podpowłoki są dostępne tylko dla podpowłoki i znikną po jej zakończeniu.

Podpowłoki są również tworzone, jeśli uruchomisz polecenie z wiersza poleceń przy użyciu ścieżki ./, ale nie zostaną utworzone, jeśli po prostu uruchomisz polecenie bez ścieżki. "

Nie jest jasne, co autor próbuje tutaj powiedzieć. W przypadku wywołania polecenia zewnętrznego, niezależnie od tego, czy jest ono wywoływane ze ścieżką, czy bez, nastąpi co następuje:
  • Muszla
               fork         
    s, aby utworzyć nowy proces.
  • Nowo utworzony proces potomny wykonuje dowolne określone przekierowanie we/wy.
  • Proces potomny wykonuje polecenie zewnętrzne, po czym procesy przestają być powłoką i stają się tym, czym jest program zewnętrzny. (Co oczywiście może być skryptem powłoki).

Jest to nowy proces, więc wszelkie zmienne ustawione przez polecenie zewnętrzne będą niedostępne dla procesu nadrzędnego, tak jakby to była podpowłoka.
Autor mógł mieć na myśli jeden z trzech następujących scenariuszy:
  • Polecenie zewnętrzne to źle sformatowany skrypt, w którym to przypadku powłoka wywołująca może pracować nad złym formatowaniem, zgadując, której powłoki użyć do zinterpretowania skryptu. (Ten scenariusz jest tak nieprzewidywalny, że zdecydowanie odradzam poleganie na nim. Prawidłowym sposobem na znalezienie tłumacza jest
               #!         
    wiersz na początku skryptu).
  • Możesz wywołać wewnętrzne polecenie, takie jak
               read         
    która składniowo wygląda jak polecenie zewnętrzne znalezione przez wyszukiwanie
               PATH         
    ... Ale nawet jeśli składniowo wygląda tak samo, będzie się zachowywać inaczej. o ile
               read         
    ustawi zmienną, która będzie używana przez następujące polecenia,
               read         
    musi się wydarzyć w obecnym procesie bez żadnego
               fork         
    połączenie. (Ze względów wydajnościowych nawet polecenia wewnętrzne, które można bezpiecznie wywołać jako podproces, najlepiej wykonywać w bieżącym procesie.
               fork         
    trochę drogie.)
  • Możesz uzyskać polecenia powłoki za pomocą
               . file         
    lub
               source file         
    ... W tym przypadku
               file         
    to nie jest scenariusz, ale jest nieco podobny. Wszystkie zespoły w
               file         
    zostanie wywołana przez bieżącą powłokę bez wcześniejszego wywołania
               fork         
    ... (Ale oczywiście zespoły w środku
               file         
    może powodować
               fork         
    połączeń). W tym przypadku dowolny
               #!         
    wyrysować
               file         
    zostaną zignorowane, a wszelkie zmienne ustawione
               file         
    będzie dostępny dla Twojej aktualnej powłoki.

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się