Czy ktoś może wyjaśnić, jakie są zastosowania polecenia exec w skryptach powłoki za pomocą prostych przykładów?
Czy ktoś może wyjaśnić, jakie są zastosowania polecenia exec w skryptach powłoki za pomocą prostych przykładów?
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, bez fork
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:
exec appln-program
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łanie ksh
. 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, że ksh
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 jak ksh
i 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 exec
powró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 -u
lub print -u
, na bash
przykład:
read <&3
echo stuff >&4
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ób exec
faktycznie pracujesz, aby zmienić deskryptor pliku? Dlaczego dla tego zadania wybrano to polecenie? (Markdown teraz zawodzi?)
exec >.\logfilename.log 2>&1
&>
jest bash
rozszerzeniem (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.
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 sh
instancję, a następnie zaczynasz command
jako dziecko tej sh
instancji. Po command
zakończeniu,sh
instancja również się kończy.
sh -c 'exec command'
biega sh
instancji, a następnie zastępuje żesh
wystąpienie z command
binarnym, 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, 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 spiffy gosh
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órej exec
następuje przekierowanie zamiast nazwy polecenia.