Przykład użycia / praktyczny przykład dla wbudowanego exec Bash


12

Rozważ to z dokumentacji wbudowanego exec Bash:

exec zastępuje powłokę bez tworzenia nowego procesu

Podaj przypadek użycia / praktyczny przykład. Nie rozumiem, jak to ma sens.

Poszukałem go i znalazłem informacje o przekierowaniu we / wy . Czy możesz to lepiej wyjaśnić?


Odpowiedzi:


18

execjest często używany w skryptach powłoki, które działają głównie jako opakowania dla uruchamiania innych plików binarnych. Na przykład:

#!/bin/sh

if stuff;
    EXTRA_OPTIONS="-x -y -z"
else
    EXTRA_OPTIONS="-a foo"
fi

exec /usr/local/bin/the.real.binary $EXTRA_OPTIONS "$@"

tak, że po zakończeniu działania opakowania, „prawdziwy” plik binarny przejmuje kontrolę i nie ma już śladu skryptu opakowania, który tymczasowo zajmował to samo miejsce w tabeli procesów. „Prawdziwy” plik binarny jest bezpośrednim dzieckiem tego, co go uruchomiło, a nie wnukiem.

W swoim pytaniu wspominasz również o przekierowaniu wejścia / wyjścia. Jest to zupełnie inny przypadek użycia execi nie ma nic wspólnego z zastąpieniem powłoki innym procesem. Kiedy execnie ma argumentów, tak:

exec 3>>/tmp/logfile

następnie przekierowania we / wy w wierszu poleceń obowiązują w bieżącym procesie powłoki, ale bieżący proces powłoki nadal działa i przechodzi do następnego polecenia w skrypcie.


1
Można powiedzieć, że te dwa przypadki są ze sobą powiązane, ponieważ execmówi powłoce, aby nie wykonywała akcji (wykonania polecenia lub przekierowania) w procesie potomnym, ale w tym samym procesie.
Stéphane Chazelas,

5

Użyłem execwbudowanej powłoki, aby uzyskać identyfikator procesu (PID) dla programu Java. Może istnieć sposób na uzyskanie PID z poziomu Javy, ale kilka lat temu nie było. Gdy proces ma swój własny PID, może zapisać go do pliku PID (poszukaj /var/run/nazw plików z sufiksem „.pid”), aby umożliwić programom zarządzającym rozpoznanie PID uruchomionego procesu i zapobiec drugiej instancji z tego samego serwera przed uruchomieniem. Działa to mniej więcej tak:

exec java -cp=YourServer.jar StartClass -p $$

Kod w main()metodzie klasy StartClassobsługuje parsowanie argumentów i może znaleźć własny identyfikator procesu.


2

Dla zabawy uruchom następujący program (przetłumaczony na wybrany język implementacji) w tle w systemie z rozliczaniem procesów użytkownika i limitami.

while(true) fork();

Teraz, gdy każde miejsce w tabeli procesów, którego możesz używać, jest pełne kopii tego uruchomionego programu, jak zamierzasz go zabić? Uruchomienie kill (1) wymaga innego gniazda procesu, którego nie możesz mieć. Przydałoby się zastąpienie powłoki przez polecenie zabicia ...

exec /bin/kill -9 -1

(Zakłada się, że twój system ma kill (1) w / bin / kill. "Exec` which kill` -9 -1 "jest potencjalnie bezpieczniejszy.) Wysyła SIGKILL do każdego procesu, jaki możesz.

(Uwaga: nie wylogowuj się z uruchomionej powłoki, chyba że limity procesu zawsze pozwalają na nowe logowanie do gniazda procesu dla jej powłoki. Może to być nieco trudniejsze do wyczyszczenia, jeśli tak zrobisz. Z pewnością nie zrobiłem tego w wczesne lata 90. Nie.)


3
(1) Ta odpowiedź byłaby nieco lepsza, gdybyś faktycznie pokazał execpolecenie przydatne w tej sytuacji. (2) Ta odpowiedź jest nieco archaiczna; killpolecenie zostało polecenie wbudowane w bash przez wiele lat, głównie z tego powodu niepokoju.
G-Man mówi „Przywróć Monikę”

@ G-Man: Rozumiesz, że twój przedmiot (2) sprawia, że ​​ta odpowiedź jest precyzyjną odpowiedzią na PO?
Eric Towers,

Nie, nie rozumiem tego. Proszę, wytłumacz mi to.
G-Man mówi „Reinstate Monica”

4
Nie idę za tobą. Pytanie nie wymaga praktycznych przykładów wszystkich wbudowanych poleceń bash; prosi o przykłady exec- a fakt, że killjest wbudowany, tak naprawdę nie ma nic wspólnego z execwbudowanym.
G-Man mówi „Przywróć Monikę”

1
Właśnie przeczytałem twoją aktualizację do twojej odpowiedzi. (1) Zgadnij co? Jeśli tabela procesów jest pełna, to podstawianie poleceń (np. `which kill`) Też nie będzie działać. (2) BTW, $(…)formularz jest zalecany zamiast `…`formularza. (3) Ale nie ma nic niebezpiecznego w zgadywaniu w katalogu. Jeśli przypadkowo wpiszesz exec /binn/kill, po prostu pojawi się komunikat o błędzie, a twoja powłoka nie zniknie. (4) Ale ty nawet nie trzeba się martwić o to, co katalog killjest.  execZastosowania $PATH, tak jak normalnych poleceń, tak exec kill …działa (zakładając, że masz /binw ścieżce wyszukiwania).
G-Man mówi „Reinstate Monica”

1
  • Jest to podobne do przykładu Bruce'a, że ​​trzeba znać PID procesu:

    (cmdpid = $ BASHPID; (sleep 300; kill "$ cmdpid") & exec long-running-command )

    w którym ty

    1. Uruchom podpowłokę (zewnętrzną (i )),
    2. Znajdź PID podpowłoki. ( $$poda ci PID głównej powłoki).
    3. Odłącz podpowłokę, która zabija twój proces po upływie limitu czasu, i
    4. Uruchom polecenie w procesie podpowłoki utworzonej w kroku 1.

    Będzie to działało long-running-command, ale tylko przez z góry określony, ograniczony czas. 

  • Jest to trochę niepoważne, ale jeśli zdecydujesz, że chcesz być rootem (lub innym użytkownikiem) do końca sesji logowania, możesz exec su.

    Właściwie mogę sobie wyobrazić scenariusz, w którym byłoby to naprawdę przydatne. Załóżmy, że jesteś zalogowany do systemu zdalnego i z jakiegoś powodu występuje problem z zerwaniem połączenia i nawiązaniem nowego połączenia. Załóżmy na przykład, że system zdalny ma zaporę ogniową zgodną z harmonogramem. Pozwolono ci się połączyć, kiedy to zrobiono, a ustanowione połączenia nie są zamykane, ale w tej chwili nowe połączenia nie są akceptowane.

    Zrobiłeś to, co chciałeś i jesteś gotowy do wylogowania. Twój przyjaciel Bob jest w pokoju z tobą i chce popracować nad systemem zdalnym - ale nie będzie mógł się połączyć. Więc piszesz exec su - bob, a kiedy pojawi się monit o hasło, oddaj mu stację roboczą. Nie ma teraz żadnego procesu z twoim identyfikatorem UID (chyba że uruchomiłeś coś w tle), więc Bob nie będzie mógł zadzierać z twoimi plikami. Skutecznie przejmie twoje połączenie (za twoją zgodą i współpracą).

    Uwagi:

    • Oczywiście to nie zadziała, jeśli nie wolno ci biegać su.
    • Zostanie zalogowany, więc być może będziesz musiał wyjaśnić komuś swoje motywy. Ponieważ obchodzisz zasady (harmonogram zapory), możesz wpaść w kłopoty.
    • Nie gwarantuję, że jest w 100% bezpieczny. Na przykład whoprawdopodobnie nadal pokaże twoje imię. Można sobie wyobrazić, że jakiś (źle napisany) program użyje tego, aby myśleć, że Bob jest tobą, i dać mu dostęp do twoich zasobów.
    • Jeśli system przeprowadza inspekcję, działania Boba mogą być kontrolowane pod Twoim nazwiskiem.

Zauważ, że w praktyce w większości powłok (a;b)jest już taki sam, jak (a;exec b)w przypadku optymalizacji powłoki dla ostatniego polecenia w podpowłoce. Jedynymi wyjątkami wydają się być bashi mksh. Korzystanie execpomaga to zagwarantować.
Stéphane Chazelas,
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.