Jakie są zastosowania polecenia exec w skryptach powłoki?

249

Czy ktoś może wyjaśnić, jakie są zastosowania polecenia exec w skryptach powłoki za pomocą prostych przykładów?

użytkownik2400564
źródło
31
Linki do linux.about.com nie są pomocne. Nie wyjaśniają w żaden sposób, w jaki sposób wykonywanie polecenia lub potoku poleceń za pomocą polecenia „exec” różni się od zwykłego wykonywania ich. Stąd pytanie OP „jakie jest zastosowanie exec”?
Jonathan Hartley
2
Stack Overflow to strona z pytaniami dotyczącymi programowania i programowania. To pytanie wydaje się nie na temat, ponieważ nie dotyczy programowania ani programowania. Zobacz o jakie tematy mogę pytać tutaj w Centrum pomocy. Być może lepiej byłoby zapytać Super User lub Unix & Linux Stack Exchange .
jww

Odpowiedzi:

281

Te execwbudowane w lusterka dowodzenia funkcje jądra, istnieje rodzina z nich opiera się naexecve , co nazywa się zwykle z C.

execzastępuje bieżący program w bieżącym procesie, bez forkwprowadzania nowego procesu. Nie jest to coś, czego można użyć w każdym pisanym skrypcie, ale przydaje się czasem. Oto kilka scenariuszy, z których korzystałem;

  1. Chcemy, aby użytkownik uruchomił określony program aplikacyjny bez dostępu do powłoki. Możemy zmienić program do logowania w / etc / passwd, ale być może chcemy, aby ustawienia środowiska były używane z plików startowych. Zatem w (powiedzmy) .profileostatnim stwierdzeniu jest coś takiego:

     exec appln-program

    więc teraz nie ma powłoki, do której można by wrócić. Nawet w przypadku appln-programawarii użytkownik końcowy nie może dostać się do powłoki, ponieważ jej nie ma - execzastąpiła ją.

  2. Chcemy użyć innej powłoki niż ta w / etc / passwd. Choć może się to wydawać głupie, niektóre witryny nie pozwalają użytkownikom zmieniać powłoki logowania. Jedna strona, którą znam, od której wszyscy zaczęli csh, i wszyscy po prostu umieścili w swoim .login(plik startowy csh) wywołanie ksh. Mimo, że to działało, pozostawił cshuruchomiony proces błądzący , a wylogowanie było dwustopniowe, które mogło się mylić. Więc zmieniliśmy go na ten, exec kshktóry właśnie zastąpił program powłoki c powłoką Korn i uprościliśmy wszystko (są z tym inne problemy, takie jak fakt, że kshnie jest to powłoka logowania).

  3. Tylko w celu zapisania procesów. Jeśli zadzwonimy prog1 -> prog2 -> prog3 -> prog4itp. I nigdy nie wrócimy, wtedy każde połączenie należy wykonać jako exec. Oszczędza zasoby (co prawda niewiele, chyba że się powtórzy) i upraszcza wyłączanie.

Najwyraźniej widziałeś exec kiedyś gdzieś byłeś używany, być może jeśli pokazałeś kod, który cię wkurza, moglibyśmy uzasadnić jego użycie.

Edycja : Zdałem sobie sprawę, że moja powyższa odpowiedź jest niepełna. Istnieją dwa zastosowania execw powłokach takich jak kshi bash- używane do otwierania deskryptorów plików. Oto kilka przykładów:

exec 3< thisfile          # open "thisfile" for reading on file descriptor 3
exec 4> thatfile          # open "thatfile" for writing on file descriptor 4
exec 8<> tother           # open "tother" for reading and writing on fd 8
exec 6>> other            # open "other" for appending on file descriptor 6
exec 5<&0                 # copy read file descriptor 0 onto file descriptor 5
exec 7>&4                 # copy write file descriptor 4 onto 7
exec 3<&-                 # close the read file descriptor 3
exec 6>&-                 # close the write file descriptor 6

Zauważ, że odstępy są tutaj bardzo ważne. Jeśli umieścisz spację między numerem fd a symbolem przekierowania, wówczas execpowróci do pierwotnego znaczenia:

  exec 3 < thisfile       # oops, overwrite the current program with command "3"

Istnieje kilka sposobów korzystania z nich, na użytek ksh read -ulub print -u, na bashprzykład:

read <&3
echo stuff >&4
cdarke
źródło
22
jest też inne zastosowanie, które znalazłem dość przydatne i warte wspomnienia tutaj, ponieważ dotyczy aplikacji internetowych w Pythonie i wydaje się, że jest coś pomiędzy (niesamowitymi) odpowiedziami 2 i 3. Zwykle uruchamiam aplikacje internetowe WSGI (powiedzmy django lub flask) przez przełożonego nazywającego się gunicorn aplikacja: ta ostatnia notorycznie wymagająca sporo zmiennych środowiskowych, jest o wiele łatwiejsza i łatwiejsza w utrzymaniu gunicorn ze skryptu powłoki, który konfiguruje wszystko i ostatecznie exec gunicornprzekazuje prawidłowy pid z powrotem do przełożonego.
gru
1
Dokumenty mówią, że execmożna użyć do przekierowania:> Jeśli polecenie nie zostanie określone, wszelkie przekierowania zostaną zastosowane w bieżącej powłoce, a zwracany status to 0. Jeśli wystąpi błąd przekierowania, zwracany status to 1. Ale w jaki sposób execfaktycznie pracujesz, aby zmienić deskryptor pliku? Dlaczego dla tego zadania wybrano to polecenie? (Markdown teraz zawodzi?)
Ray
@Ray: najlepiej, jak mogę: pubs.opengroup.org/onlinepubs/009604599/utilities/exec.html . Jeśli chcesz wiedzieć, jak to zrobić, spójrz na kod źródłowy powłoki.
cdarke
7
Inne zastosowanie: Przekieruj wszystkie dane wyjściowe skryptu do pliku dziennikaexec >.\logfilename.log 2>&1
Hogan
1
@Carmageddon: &>jest bashrozszerzeniem (patrz man bash), a twój przykład jest równoważny exec >/var/log/userdata.log 2>&1. Innymi słowy przekierowuje stdout i stderr do tego pliku. Następujące polecenia odziedziczą te przekierowania, chyba że zostaną zresetowane, ale zostaną wykonane.
cdarke
41

Aby uzupełnić przyjętą odpowiedź krótką, przyjazną dla początkujących krótką odpowiedzią, prawdopodobnie nie potrzebujesz exec.

Jeśli nadal tu jesteś, poniższa dyskusja powinna mieć nadzieję, dlaczego. Kiedy biegniesz, powiedz

sh -c 'command'

uruchamiasz shinstancję, a następnie zaczynasz commandjako dziecko tej shinstancji. Po commandzakończeniu,sh instancja również się kończy.

sh -c 'exec command'

biega shinstancji, a następnie zastępuje żesh wystąpienie z commandbinarnym, i biegnie, że zamiast.

Oczywiście oba są bezużyteczne w tym ograniczonym kontekście; po prostu chcesz

command

Istnieją pewne skrajne sytuacje, w których chcesz, aby powłoka odczytała plik konfiguracyjny lub w inny sposób skonfigurowała środowisko jako przygotowanie do uruchomienia command. Jest to właściwie jedyna sytuacja, w którejexec command jest przydatna.

#!/bin/sh
ENVIRONMENT=$(some complex task)
exec command

Robi to pewne rzeczy, aby przygotować środowisko, aby zawierało to, co jest potrzebne. Gdy to zrobisz, shinstancja nie jest już potrzebna, więc jest to (niewielka) optymalizacja po prostu zastąpićsh instancję commandprocesem, a nie miećsh uruchamiać go jako proces potomny i czekać na niego, a następnie zakończyć, jak tylko się zakończy.

Podobnie, jeśli chcesz zwolnić jak najwięcej zasobów dla ciężkiej komendy na końcu skryptu powłoki, możesz exec to polecenie jako optymalizację.

Jeśli coś zmusza Cię do uruchomienia, shale naprawdę chciałbyś uruchomić coś innego, exec something elsejest to oczywiście obejście zastępujące niepożądaną shinstancję (na przykład, jeśli naprawdę chciałbyś uruchomić własny spiffy goshzamiast, shale twój nie jest wymieniony w/etc/shells więc możesz podaj go jako powłokę logowania).

Drugie zastosowanie execdo manipulowania deskryptorami plików to osobny temat. Przyjęta odpowiedź ładnie to obejmuje; aby zachować ten samowystarczalność, po prostu odłożę się do instrukcji, po której execnastępuje przekierowanie zamiast nazwy polecenia.

potrójny
źródło
2
Oprzeć się pokusie, by nazwać swoją fajny skorupę bush. Oczywiście dotyczy to również bashogólnie popularnej powłoki uniksowej; chociaż, jak zauważa @anishsane , Bash potajemnie optymalizuje się bash -c 'command'poprzez faktyczne działanie exec command.
tripleee
1
Kod wyjścia powłoki jest ogólnie kodem wyjścia ostatniego wykonanego polecenia. Oczywiście, jeśli powłoka nie uruchomi się lub nie wykona polecenia, status wyjścia powłoki odzwierciedli to odpowiednim kodem błędu.
tripleee
2
@JonathanLeffler Celowo dokumentuję antypattern, który widzę w pytaniach dla początkujących. Ten podpowiedział ten duplikat, ale widziałem go już wcześniej, więc chciałem to szczegółowo opisać.
tripleee
2
@JathanathanLeffler Drobne poprawki w tekście; czy to wystarczy? Dziękujemy za opinię.
tripleee
2
Dzięki - dodałem kolejny krótki akapit na temat tej optymalizacji. Nie jest dla mnie jasne, czy masz inne obiekcje, czy chcesz wyjaśnić wszystko z innej strony.
tripleee