Nie rozumiem polecenia bash exec
. Widziałem, jak był używany w skryptach do przekierowywania wszystkich danych wyjściowych do pliku (jak pokazano w tym ). Ale nie rozumiem, jak to działa ani co ogólnie robi. Przeczytałem strony podręcznika, ale ich nie rozumiem.
108
exec
w specjalny sposób, który można wyjaśnić znacznie prościej, napiszę odpowiedź.Odpowiedzi:
man bash
mówi:Ważne są dwa ostatnie wiersze: jeśli uruchomisz
exec
się sam, bez polecenia, po prostu sprawi, że przekierowania zostaną zastosowane do bieżącej powłoki. Prawdopodobnie wiesz, że po uruchomieniucommand > file
dane wyjściowecommand
są zapisywane w miejscufile
zamiast w terminalu (nazywa się to przekierowaniem ). Jeśli uruchomiszexec > file
zamiast tego, przekierowanie dotyczy całej powłoki: Wszelkie dane wyjściowe wytworzone przez powłokę są zapisywanefile
zamiast do terminala. Na przykład tutajNajpierw zaczynam nową
bash
powłokę. Następnie w tej nowej powłoce uruchamiamexec > file
, aby wszystkie dane wyjściowe były przekierowywane dofile
. Rzeczywiście, po tym uruchamiam,date
ale nie otrzymuję danych wyjściowych, ponieważ dane wyjściowe są przekierowywane dofile
. Następnie zamykam moją powłokę (aby przekierowanie przestało obowiązywać) i widzę, żefile
rzeczywiście zawiera ona wynikdate
polecenia, które uruchomiłem wcześniej.źródło
exec
służy również do zastąpienia bieżącego procesu powłoki poleceniem, dzięki czemu rodzic idzie drogą, a dziecko posiada pid. Dotyczy to nie tylko przekierowania. Dodaj tę informacjęexec nginx <various nginx arguments>
. Oznacza to, że nginx przejmuje pid skryptu bash, a teraz nginx jest głównym działającym procesem kontenera, a nie skryptem. Zakładam, że to tylko ze względu na czystość, chyba że ktoś inny zna bardziej konkretny powód?gnome-terminal
przynajmniej 14.04 miał skrypt otoki do ustawiania argumentów. I to jest ich jedyny cel, naprawdę - sztuka i środowisko. Innym przypadkiem byłoby posprzątanie - zabicie poprzedniej instancji procesu i uruchomienie nowejexec
przykład podobny donginx
przykładu podanego przez @LukeGriffiths jest~/.vnc/xstartup
skrypt, któryvncserver
wykorzystuje się do konfigurowania serwera VNC proces, a następnieexec gnome-session
alboexec startkde
i tak dalej.exec
skryptu uruchamiania kontenera jest to, że PID 1, ENTRYPOINT kontenera, ma szczególne znaczenie w Docker. Jest to główny proces, który odbiera sygnały, a gdy już istnieje, kontener również wychodzi.exec
po prostu sposób nash
usunięcie tego łańcucha poleceń i uczynienie demona głównym procesem kontenera.exec
jest poleceniem o dwóch bardzo różnych zachowaniach, w zależności od tego, czy użyto z nim co najmniej jednego argumentu, czy też nie użyto żadnego argumentu.Jeśli przekazany zostanie co najmniej jeden argument, pierwszy zostanie przyjęty jako nazwa polecenia i
exec
spróbuje wykonać go jako polecenie przekazujące pozostałe argumenty, jeśli takie istnieją, do tego polecenia i zarządza ewentualnymi przekierowaniami.Jeśli polecenie przekazane jako pierwszy argument nie istnieje, bieżąca powłoka, a nie tylko polecenie exec, kończy działanie błędnie.
Jeśli polecenie istnieje i jest wykonywalne, zastępuje bieżącą powłokę. Oznacza to, że jeśli
exec
pojawi się w skrypcie, instrukcje następujące po wywołaniu exec nigdy nie zostaną wykonane (chyba żeexec
samo jest w podpowłoce).exec
nigdy nie wraca. Pułapki typu „EXIT” również nie zostaną uruchomione.Jeśli nie zostanie przekazany żaden argument,
exec
służy jedynie do przedefiniowania bieżących deskryptorów plików powłoki. Powłoka jest kontynuowana poexec
, w przeciwieństwie do poprzedniego przypadku, ale standardowe przekierowanie wejścia, wyjścia, błędu lub dowolnego deskryptora pliku zostało przekierowane.Jeśli niektóre z przekierowań zostaną użyte
/dev/null
, wszelkie dane wejściowe zwrócą EOF, a wszelkie dane wyjściowe zostaną odrzucone.Możesz zamknąć deskryptory plików, używając
-
jako źródła lub miejsca docelowego, npexec <&-
. Kolejne odczytywanie lub zapisywanie nie powiedzie się.Oto dwa przykłady:
Ten skrypt wyświetli „foo” jako polecenie cat, zamiast czekać na dane wejściowe użytkownika, tak jak w zwykłym przypadku, pobierze dane wejściowe z pliku / tmp / bar, który zawiera foo.
Ten skrypt wyświetli
4
(liczbę bajtów w / tmp / bar) i natychmiast się zakończy.cat
Polecenie nie zostanie wykonane.źródło
/dev/null
, więc zapisy nadal kończą się powodzeniem, a odczyty zwracają EOF.close(2)
na fd spowoduje, że wywołania systemowe odczytu / zapisu zwrócą błędy, a ty zrobisz toexec 2>&-
na przykład.exec 3</dev/null;
ls -l /proc/self/fd
pamiętaj, że fd 3 będzie otwarty tylko do odczytu na / dev / null. Następnie zamknij go ponownie za pomocąexec 3<&-
, i zobaczysz (ls -l /proc/$$/fd
ponownie), że twój proces powłoki nie ma już FD 3. (zamykanie standardowego wejściaexec <&-
może być przydatne w skryptach, ale interaktywnie jest to wylogowanie).exec
obecnie najbardziej uprzywilejowanej odpowiedzi, mówi tylko o jednym przypadku użycia, a druga odpowiedź g_p mówi tylko o drugim przypadku użycia. Ta odpowiedź jest miła i zwięzła / czytelna w przypadku tak złożonego tematu.Aby zrozumieć
exec
, musisz najpierw zrozumiećfork
. Staram się streścić.Kiedy dojeżdżasz do rozwidlenia drogi, zazwyczaj masz dwie opcje. Programy Linuksa docierają do tego rozwidlenia w drodze, gdy uderzą w
fork()
wywołanie systemowe.Normalne programy to polecenia systemowe, które istnieją w skompilowanej formie w systemie. Po uruchomieniu takiego programu tworzony jest nowy proces. Ten proces potomny ma takie samo środowisko jak jego rodzic, tylko numer identyfikacyjny procesu jest inny. Ta procedura nazywa się rozwidleniem .
exec
jest używany.exec
zastąpi zawartość aktualnie uruchomionego procesu informacjami z pliku binarnego programu.źródło
exec
można przekierować wyjście skryptu, tak jak w linku, który zamieściłem?W
bash
, jeśli zrobiszhelp exec
:Odpowiedni bit:
exec
jest wbudowaną powłoką , która jest odpowiednikiem powłokiexec
rodziny wywołań systemowych , o których mówi G_P (i których stronom wydaje się, że przeczytałeś). Ma tylko obowiązkową funkcję POSIX wpływania na bieżącą powłokę, jeśli nie podano polecenia.źródło