jobs — Shell-Jobs starten, anhalten und in den Hintergrund schicken
Job-Control der Shell mit jobs, fg, bg, &, Ctrl+Z und disown: Prozesse in einer interaktiven Shell starten, anhalten, fortsetzen und ablösen.
Sobald ein Kommando länger läuft, willst du dein Terminal nicht blockieren – genau dafür gibt es die Job-Control der Shell. Mit &, Ctrl+Z, jobs, fg, bg und disown startest du Prozesse im Hintergrund, hältst sie an, holst sie zurück oder löst sie ganz vom Terminal. Dieser Guide zeigt dir die Builtins und Job-Spezifizierer, mit denen du mehrere Aufgaben gleichzeitig im Griff behältst – vom schnellen sleep 300 & bis zur begrenzten parallelen Warteschlange.
Jobs starten
<command> & — Führt ein Kommando im Hintergrund aus. Die Shell gibt „[n] PID" aus und kehrt sofort zurück.
sleep 300 &<command1> & <command2> & <command3> & — Startet mehrere Hintergrundjobs in einer Zeile.
make build & make docs & make test &( <command> & ) — Führt ein Kommando in einer Subshell aus, sodass es den Elternprozess überlebt und nicht in „jobs" auftaucht.
( long-running-task & )<command> &! — Zsh: startet im Hintergrund UND löst sofort ab (disown) — überlebt das Beenden der Shell, kein SIGHUP.
long-running-task &!<command> |& — Schickt eine Pipeline samt stderr in den Hintergrund (bash 4+, zsh).
make 2>&1 | tee build.log &Jobs anhalten
Ctrl+Z — Sendet SIGTSTP an den Vordergrundprozess — hält ihn an und gibt die Kontrolle an die Shell zurück.
vim file.txt # mit Ctrl+Z anhalten, mit fg zurückholenCtrl+Y — Sendet SIGTSTP erst, wenn der Prozess Eingaben lesen will (verzögertes Anhalten, nur BSD/macOS).
less bigfile # Ctrl+Y hält beim nächsten Lesezugriff ankill -STOP <pid> — Hält einen beliebigen Prozess per PID an (nicht nur den im Vordergrund).
kill -STOP 4242kill -CONT <pid> — Setzt einen angehaltenen Prozess per PID fort — das Gegenstück zu -STOP.
kill -CONT 4242Jobs auflisten
jobs — Listet alle Jobs der aktuellen Shell mit Nummer, Status und Kommando auf.
$ jobs
[1]+ Running sleep 300 &
[2]- Stopped vim file.txtjobs -l — Listet Jobs inklusive ihrer PID auf.
jobs -ljobs -p — Gibt nur die PIDs der Jobs aus (eine pro Zeile) — praktisch fürs Skripting.
jobs -p | xargs killjobs -r — Listet nur laufende Jobs auf.
jobs -rjobs -s — Listet nur angehaltene Jobs auf.
jobs -sjobs -n — Listet nur Jobs auf, deren Status sich seit der letzten Benachrichtigung geändert hat.
jobs -njobs %<n> — Zeigt den Status eines bestimmten Jobs.
jobs %1Job-Spezifizierer
%<n> — Bezieht sich auf Jobnummer n (die von „jobs" angezeigte Nummer).
fg %2%% or %+ — Der aktuelle Job (zuletzt angehalten oder in den Hintergrund geschickt). Implizites Ziel von „fg"/„bg" ohne Argumente.
fg %%%- — Der vorige Job (der vor %+).
fg %-%<string> — Job, dessen Kommando mit der angegebenen Zeichenkette beginnt.
fg %vim%?<string> — Job, dessen Kommando die angegebene Zeichenkette irgendwo enthält.
kill %?makeVordergrund & Hintergrund
fg — Holt den aktuellen (zuletzt verwendeten) Job in den Vordergrund.
fgfg %<n> — Holt Jobnummer n in den Vordergrund.
fg %1bg — Setzt den aktuell angehaltenen Job im Hintergrund fort (läuft weiter, aber ohne Terminal-Eingabe).
Ctrl+Z, dann „bg", um losgelöst weiterzulaufenbg %<n> — Setzt einen bestimmten angehaltenen Job im Hintergrund fort.
bg %2%<n> — Ein nackter Job-Spezifizierer holt den Job in den Vordergrund (Kurzform für „fg %n").
%1%<n> & — Ein nackter Job-Spezifizierer mit „&" setzt ihn im Hintergrund fort (Kurzform für „bg %n").
%1 &Jobs beenden & Signale senden
kill %<n> — Sendet SIGTERM an einen Job per Jobnummer.
kill %1kill -9 %<n> — Erzwingt das Beenden (SIGKILL) eines Jobs, der sich nicht beenden lässt.
kill -9 %2kill -<signal> %<n> — Sendet ein beliebiges Signal per Name oder Nummer an einen Job.
kill -HUP %1kill %<string> — Beendet den Job, dessen Kommando mit
kill %makekill $(jobs -p) — Sendet SIGTERM an alle aktuellen Jobs der Shell.
kill $(jobs -p)Jobs ablösen (disown)
disown — Entfernt den jüngsten Job aus der Job-Tabelle der Shell — er läuft weiter, wird aber nicht mehr verfolgt.
long-task & disowndisown %<n> — Löst einen bestimmten Job per Nummer ab.
disown %2disown -h %<n> — Behält den Job in der Tabelle, markiert ihn aber so, dass er beim Beenden der Shell KEIN SIGHUP erhält.
disown -h %1disown -a — Löst alle Jobs von der Shell ab.
disown -adisown -r — Löst nur laufende Jobs ab (lässt angehaltene in der Tabelle).
disown -rshopt -s huponexit — Bash: sendet beim Beenden der Shell SIGHUP an alle Jobs (Standard ist AUS — sie überleben).
shopt -s huponexitsetopt nohup — Zsh: sendet beim Beenden der Shell KEIN SIGHUP an die Jobs.
setopt nohupAuf Jobs warten
wait — Blockiert, bis alle Hintergrundjobs der aktuellen Shell beendet sind.
task1 & task2 & task3 & waitwait %<n> — Wartet auf einen bestimmten Job — der Exit-Status von wait entspricht dem des Jobs.
long-task & wait %1; echo "exited $?"wait <pid> — Wartet auf eine bestimmte PID (ab bash 5.1+ auch auf Hintergrundjobs außerhalb der aktuellen Shell).
wait 4242wait -n — Wartet auf IRGENDEINEN einzelnen Hintergrundjob (bash 4.3+, zsh). Nützlich für parallele Warteschlangen.
for i in 1 2 3; do task $i & done; wait -nwait -f <pid> — Wartet, bis der Prozess tatsächlich endet, selbst wenn sein Elternprozess ihn bereits eingesammelt hat (bash 5.1+).
wait -f 4242Muster & Fallstricke
command > out.log 2>&1 & — Schickt ein Kommando in den Hintergrund und leitet stdout und stderr in eine Datei (sonst landet streunende Ausgabe im Terminal).
make build > build.log 2>&1 &command < /dev/null > out.log 2>&1 & — Löst vollständig von Terminal-stdin/-stdout — kein SIGTTIN/SIGTTOU, wenn das Terminal geschlossen wird.
long-task < /dev/null > out.log 2>&1 &set -m / set +m — Schaltet die Job-Control ein oder aus. In Skripten standardmäßig aus — mit „set -m" einschalten, um %n im Skript zu nutzen.
set -m; long-task & fg %1set -b — Bash: meldet Statusänderungen von Jobs SOFORT statt erst vor dem nächsten Prompt.
set -b$! — PID des zuletzt in den Hintergrund geschickten Prozesses — kombiniere sie mit „wait" oder „kill", um einen bestimmten Job zu verfolgen.
long-task & echo $! > task.pidtrap 'kill $(jobs -p) 2>/dev/null' EXIT — Aufräumen: beendet alle Kind-Jobs, wenn die Shell oder das Skript endet.
trap 'kill $(jobs -p) 2>/dev/null' EXITPraxisrezepte
Ctrl+Z, bg, disown — Befördert ein Vordergrundkommando zu einem vollständig losgelösten Hintergrundprozess — überlebt den Logout.
tail -f big.log # Ctrl+Z
bg
disownfor f in *.mp4; do ffmpeg ... "$f" & done; wait — Verarbeitet einen Stapel parallel und wartet, bis alles fertig ist.
for f in *.mp4; do ffmpeg -i "$f" "${f%.mp4}.webm" & done; waitParallele Warteschlange mit -n (max. parallel) — Verarbeitet Arbeitsaufträge mit einer begrenzten Anzahl paralleler Jobs.
max=4; for i in {1..20}; do (( $(jobs -r | wc -l) >= max )) && wait -n; task $i & done; waitkill %1 && wait %1 2>/dev/null — Beendet einen Job und wartet, bis die Shell ihn vollständig eingesammelt hat (unterdrückt die „Terminated"-Meldung).
kill %1 && wait %1 2>/dev/null Fazit
Die Job-Control macht aus einer einzelnen Shell einen kleinen Prozess-Manager: jobs verschafft dir den Überblick, Ctrl+Z plus bg befördert ein hängendes Kommando in den Hintergrund, und fg holt es wieder zurück. Wichtig zu wissen: Hintergrundjobs hängen am Terminal. Beendest du die Shell oder loggst dich aus, erhalten sie standardmäßig ein SIGHUP und sterben – mitsamt noch nicht gespeicherter Arbeit. Soll ein Job das Logout überleben, löse ihn mit disown -h ab oder starte ihn gleich unter nohup, screen oder tmux. Und denk daran: Diese Builtins wirken nur in einer interaktiven Shell; in Skripten musst du die Job-Control erst mit set -m aktivieren.
Weiterführende Links
- GNU Bash: Job Control – die offizielle Bash-Referenz zu Vorder- und Hintergrundjobs sowie Signalen (englisch)
- Wikipedia: Hintergrundprozess – Erklärung von Vorder- und Hintergrundprozessen unter Unix