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;
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ą.
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).
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:
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?)
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.
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.
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.
Odpowiedzi:
Te
exec
wbudowane w lusterka dowodzenia funkcje jądra, istnieje rodzina z nich opiera się naexecve
, co nazywa się zwykle z C.exec
zastępuje bieżący program w bieżącym procesie, bezfork
wprowadzania 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;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)
.profile
ostatnim stwierdzeniu jest coś takiego:więc teraz nie ma powłoki, do której można by wrócić. Nawet w przypadku
appln-program
awarii użytkownik końcowy nie może dostać się do powłoki, ponieważ jej nie ma -exec
zastąpiła ją.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łanieksh
. Mimo, że to działało, pozostawiłcsh
uruchomiony proces błądzący , a wylogowanie było dwustopniowe, które mogło się mylić. Więc zmieniliśmy go na ten,exec ksh
któ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, żeksh
nie jest to powłoka logowania).Tylko w celu zapisania procesów. Jeśli zadzwonimy
prog1 -> prog2 -> prog3 -> prog4
itp. 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
exec
w powłokach takich jakksh
ibash
- używane do otwierania deskryptorów plików. Oto kilka przykładów:Zauważ, że odstępy są tutaj bardzo ważne. Jeśli umieścisz spację między numerem fd a symbolem przekierowania, wówczas
exec
powróci do pierwotnego znaczenia:Istnieje kilka sposobów korzystania z nich, na użytek ksh
read -u
lubprint -u
, nabash
przykład:źródło
exec gunicorn
przekazuje prawidłowy pid z powrotem do przełożonego.exec
moż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óbexec
faktycznie pracujesz, aby zmienić deskryptor pliku? Dlaczego dla tego zadania wybrano to polecenie? (Markdown teraz zawodzi?)exec >.\logfilename.log 2>&1
&>
jestbash
rozszerzeniem (patrzman bash
), a twój przykład jest równoważnyexec >/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.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
uruchamiasz
sh
instancję, a następnie zaczynaszcommand
jako dziecko tejsh
instancji. Pocommand
zakończeniu,sh
instancja również się kończy.biega
sh
instancji, a następnie zastępuje żesh
wystąpienie zcommand
binarnym, i biegnie, że zamiast.Oczywiście oba są bezużyteczne w tym ograniczonym kontekście; po prostu chcesz
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.Robi to pewne rzeczy, aby przygotować środowisko, aby zawierało to, co jest potrzebne. Gdy to zrobisz,
sh
instancja nie jest już potrzebna, więc jest to (niewielka) optymalizacja po prostu zastąpićsh
instancjęcommand
procesem, 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,
sh
ale naprawdę chciałbyś uruchomić coś innego,exec something else
jest to oczywiście obejście zastępujące niepożądanąsh
instancję (na przykład, jeśli naprawdę chciałbyś uruchomić własny spiffygosh
zamiast,sh
ale twój nie jest wymieniony w/etc/shells
więc możesz podaj go jako powłokę logowania).Drugie zastosowanie
exec
do 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órejexec
następuje przekierowanie zamiast nazwy polecenia.źródło
bush
. Oczywiście dotyczy to równieżbash
ogólnie popularnej powłoki uniksowej; chociaż, jak zauważa @anishsane , Bash potajemnie optymalizuje siębash -c 'command'
poprzez faktyczne działanieexec command
.