Przejdź do głównej zawartości

exec


  • exec – specjalny builtin specyfikacji POSIX pozwalający:

    • uruchomić wskazane polecenie w miejsce bieżącej powłoki (bez tworzenia procesu potomnego),
    • lub otworzyć/zamknąć/przekierować deskryptory plików w kontekście aktualnej powłoki (np. exec 3>plik).
  • Stosowany w skryptach startowych, kontenerach (PID 1), demonyzacji procesów, zaawansowanych konstrukcjach przekierowań i optymalizacji (eliminacja forka).

  • Dostępny w Bourne sh, Bash, Zsh, Dash, BusyBox, KornShell – składnia opcji (-c/-l/-a) może się różnić między implementacjami.


Okno terminala
# Zastąpienie procesu powłoki
exec [-cl] [-a argv0] [--] polecenie [argumenty]
# Zarządzanie deskryptorami (bez polecenia)
exec [przekierowania]
  • Gdy polecenie nie jest podane, exec wpływa wyłącznie na deskryptory otwarte/zmienione w przekierowaniach.

  • Opcje w Bash ≥ 4:

    • -c – czyści środowisko, pozostawiając zmienne z linii poleceń.
    • -l – ustawia pierwszy znak argv[0] na dash (-), tworząc tryb login.
    • -a argv0 – ustawia konkretną wartość argv[0] dla uruchamianego programu.

ElementOpis
polecenieProgram lub funkcja powłoki zastępująca bieżący proces.
argumentyParametry przekazywane do nowego programu.
-cUruchom bez dziedziczenia środowiska (GNU/Bash).
-lSymuluje login shell poprzez zmianę argv[0].
-a <nazwa>Ustawia własne argv[0] (widoczne w ps).
n>plik, n<plikOtwiera plik i przypisuje do deskryptora n.
n>&m, n<&mDuplikuje deskryptor m na n.
n>&-, n<&-Zamyka deskryptor n.

POSIX: Jedyną przenośną opcją jest brak opcji; -c, -l, -a to rozszerzenia Basha/Ksh.


Okno terminala
# 1. Replacing shell with python script (no extra PID)
exec python3 app.py # po tym wierszu skrypt się nie wykonuje dalej
# 2. Uruchomienie procesu jako "login" i z niestandardową nazwą
exec -a "mydaemon" -l /usr/bin/someservice --foreground
# 3. Otwarcie pliku do odczytu i zapis pod FD 3
exec 3<>log.txt
echo "Start $(date)" >&3 # zapis przez fd 3
read -r firstline <&3 # odczyt z fd 3
exec 3>&- # zamknięcie
# 4. Przekierowanie stdout skryptu do pliku bez forka
exec >result.txt # od tej linii wszystko trafia do result.txt
echo "Linia w pliku"
# 5. Daemonizacja – zamknięcie FD 0‑2 i przekierowanie do /dev/null
exec 0</dev/null 1>/dev/null 2>&1

  • Brak powrotu: Po exec cmd kod skryptu dalej nie jest wykonywanyexec nie wraca, a kod wyjścia skryptu to kod wyjścia nowego programu.
  • PID zachowany: Program startuje z tym samym PID co powłoka – kluczowe w initach i systemd ExecStart= z Type=forking.
  • Przenośność FD: Numer deskryptora 3 i wyższe są zazwyczaj wolne, ale nie gwarantuje tego środowisko – sprawdź lsof -p $$.
  • Alternatywy: Dla modyfikacji środowiska bez zamiany procesu użyj env VAR=... cmd.
  • Bezpieczeństwo: Niewłaściwe zamknięcie FD może pozbawić programu stdout/stderr – przy debugowaniu użyj exec 2>debug.log zamiast pełnego przekierowania.

Błąd / ZachowaniePrzyczynaRozwiązanie
Skrypt “znika” po execZamieniono powłokę, kolejne linie nie wykonują sięPrzenieś kod przed exec lub uruchom polecenie bez exec.
command not found mimo poprawnej ścieżkiexec -c zeruje $PATHUstaw PATH= w tej samej linii lub unikaj -c.
Proces nie zapisuje logówstdout/stderr przekierowane do /dev/nullNie przekierowuj FD 1/2 lub użyj pliku logu.
exec: Bad file descriptorPróba użycia zamkniętego FDZweryfikuj kolejność exec 3>&- oraz odwołań.