Einführung
Ein laufendes Linux-System besteht aus mehr als nur seinen Dateien. Der Kernel verwaltet Hardware und Prozesse, jeder Befehl läuft als Prozess mit einer eigenen Kennung, und die Shell verfolgt Jobs im Vorder- und Hintergrund. Administratoren verschaffen sich zunächst einen Überblick über diesen Zustand und greifen anschließend gezielt auf den kleinsten relevanten Prozess ein.
In diesem Lab identifizieren Sie Betriebssystem und Kernel, interpretieren Laufzeit und Load Averages, untersuchen Prozessbeziehungen, finden Prozesse anhand ihres Namens, senden Beendigungssignale, üben die interaktive Jobsteuerung, werten Exit-Status aus, führen mit nohup einen losgelösten Befehl aus und lesen aktuelle Kernelmeldungen.
System identifizieren und Auslastung interpretieren
In diesem Schritt identifizieren Sie Kernel und Distribution, prüfen, wie lange das System bereits läuft, und lernen, was Load Averages aussagen.
Erstellen Sie einen Arbeitsbereich und wechseln Sie hinein:
mkdir -p /home/labex/project/process-lab
cd /home/labex/project/process-lab
Der Befehl uname gibt Informationen zum Kernel aus. Mit den Optionen -s, -r und -m wählen Sie Kernelname, Kernelversion und Rechnerarchitektur aus:
uname -srm
uname -a zeigt alle verfügbaren Felder in einer Zeile an:
uname -a
Der Kernel ist nicht dasselbe wie die Linux-Distribution. Lesen Sie die Metadaten der Distribution aus:
cat /etc/os-release
Achten Sie auf Felder wie NAME, VERSION und ID. Prüfen Sie anschließend Laufzeit und Auslastung:
uptime
Die Ausgabe enthält die aktuelle Uhrzeit, die bisherige Laufzeit des Systems, die Anzahl der angemeldeten Benutzer sowie drei Load Averages. Diese Werte beschreiben die durchschnittliche Anzahl ausführbarer oder nicht unterbrechbarer Aufgaben über ungefähr 1, 5 und 15 Minuten. Sie sind keine Prozentangaben; ihre Bedeutung hängt teilweise von der Anzahl der CPU-Kerne ab.
Zeigen Sie den kompakten Auslastungseintrag des Kernels an:
cat /proc/loadavg
Die ersten drei Werte entsprechen den Load Averages. Die nachfolgenden Felder zeigen ausführbare Aufgaben und die zuletzt vergebene Prozess-ID.
Speichern Sie eine kurze Systemübersicht zur späteren Verwendung:
uname -srm > system-summary.txt
uptime >> system-summary.txt
cat system-summary.txt
Die Datei sollte eine Kernelzeile und eine Laufzeitzeile enthalten.
Prozesse und Ressourcenaktivität untersuchen
In diesem Schritt untersuchen Sie Prozesskennungen, Eltern-Kind-Beziehungen und Zustände und erstellen eine Momentaufnahme der Systemressourcen.
Ein Prozess ist ein laufendes Programm. Jeder Prozess besitzt eine Prozess-ID, kurz PID. Die meisten Prozesse haben außerdem eine Parent Process ID, kurz PPID, die den Prozess bezeichnet, der sie gestartet hat.
Der Befehl ps zeigt eine Momentaufnahme der Prozesse an. Wählen Sie nützliche Felder aus und sortieren Sie nach PID:
cd /home/labex/project/process-lab
ps -eo pid,ppid,user,stat,comm --sort=pid | head -n 15
Die Option -e wählt alle Prozesse aus, während -o die Spalten festlegt:
PIDist die Prozesskennung.PPIDist die Kennung des übergeordneten Prozesses.USERist der Besitzer des Prozesses.STATenthält den Prozesszustand sowie optionale Kennzeichen.COMMANDist der Name der ausführbaren Datei.
Zu den häufigsten Zustandsbuchstaben gehören R für laufend, S für unterbrechbaren Schlaf, D für nicht unterbrechbaren Schlaf, T für angehalten und Z für Zombie. Ein schlafender Prozess wartet häufig einfach auf neue Arbeit.
Die Variante ps aux im BSD-Stil liefert zusätzlich CPU- und Speicherspalten sowie vollständige Befehlszeilen:
ps aux | head -n 10
top aktualisiert seine Anzeige im interaktiven Betrieb fortlaufend. Der Batch-Modus erstellt eine einzelne stabile Momentaufnahme: -b aktiviert die Batch-Ausgabe und -n 1 fordert genau eine Aktualisierung an.
top -b -n 1 | head -n 12
Die Kopfzeile fasst Laufzeit, Load Averages, Aufgabenzustände, CPU-Auslastung und Speicher zusammen. Die darunter angezeigte Prozesstabelle hilft dabei, aktive Ressourcenverbraucher zu finden.
Öffnen Sie nun die interaktive Anzeige:
top
Beobachten Sie die Aktualisierung der Werte, suchen Sie die Spalten %CPU und %MEM und drücken Sie anschließend q, um zur Shell zurückzukehren. Das interaktive top eignet sich zum Beobachten zeitlicher Veränderungen; der Batch-Modus ist besser, wenn die Ausgabe gespeichert oder weiterverarbeitet werden soll.
Speichern Sie eine fokussierte Prozessmomentaufnahme als überprüfbares Ergebnis:
ps -eo pid,ppid,user,stat,comm --sort=pid > process-snapshot.txt
head -n 5 process-snapshot.txt
Einen Übungsprozess starten und finden
In diesem Schritt starten Sie einen ungefährlichen Hintergrundprozess, speichern seine PID und finden ihn sowohl mit ps als auch mit pgrep.
Das abschließende & weist die Shell an, einen Befehl im Hintergrund auszuführen und sofort wieder die Eingabeaufforderung anzuzeigen. Starten Sie einen fünf Minuten dauernden sleep-Prozess mit dem sichtbaren Namen labex-worker:
cd /home/labex/project/process-lab
bash -c 'exec -a labex-worker sleep 300' &
Der spezielle Shell-Wert $! enthält die PID des zuletzt gestarteten Hintergrundprozesses. Speichern Sie sie, bevor Sie einen weiteren Hintergrundbefehl starten:
worker_pid=$!
echo "$worker_pid" > worker.pid
Untersuchen Sie genau diesen Prozess. Mit -p wählen Sie eine PID aus, während -o die Felder festlegt:
ps -o pid,ppid,user,stat,etime,args -p "$worker_pid"
ETIME zeigt die vergangene Laufzeit, während ARGS den sichtbaren Prozessnamen enthält. Verwenden Sie pgrep -f, um die vollständige Befehlszeile zu durchsuchen; mit -a wird sie ebenfalls ausgegeben:
pgrep -af labex-worker
Die von pgrep ausgegebene PID sollte mit dem Inhalt von worker.pid übereinstimmen. Die Suche mit einem präzisen Muster ist sicherer, als auf jeden Prozess mit einem allgemeinen Namen einzuwirken.
Prozesse mit Signalen beenden
In diesem Schritt fordern Sie zunächst mit SIGTERM eine geordnete Beendigung an und verwenden SIGKILL nur für einen Prozess, der diese Aufforderung absichtlich ignoriert.
Der Befehl kill sendet ein Signal an eine PID. Ohne explizite Signalangabe wird SIGTERM, also Signal 15, gesendet. SIGTERM fordert ein geordnetes Herunterfahren an und gibt dem Prozess Gelegenheit, aufzuräumen.
Lesen Sie die PID des Arbeitsprozesses ein und senden Sie SIGTERM:
cd /home/labex/project/process-lab
worker_pid=$(cat worker.pid)
kill "$worker_pid"
sleep 1
Der erwartete Fehler von ps bestätigt, dass der Prozess beendet wurde:
ps -p "$worker_pid" || echo "labex-worker stopped after SIGTERM"
Starten Sie nun einen kontrollierten Prozess, der SIGTERM absichtlich ignoriert:
bash -c 'trap "" TERM; exec -a labex-stubborn sleep 300' &
stubborn_pid=$!
echo "$stubborn_pid" > stubborn.pid
Geben Sie der neuen Shell einen Moment Zeit, ihren Signal-Handler einzurichten:
sleep 1
Senden Sie SIGTERM, warten Sie kurz und untersuchen Sie den Prozess:
kill -TERM "$stubborn_pid"
sleep 1
ps -o pid,stat,args -p "$stubborn_pid"
Der Prozess sollte weiterhin vorhanden sein, da dieser Übungsprozess SIGTERM ignoriert. SIGKILL, Signal 9, kann weder abgefangen noch ignoriert werden. Verwenden Sie es erst, wenn ein geordnetes Signal wirkungslos geblieben ist:
kill -KILL "$stubborn_pid"
Warten Sie den beendeten Hintergrundjob ab. Der Status ungleich null ist zu erwarten; || true ermöglicht daher die Fortsetzung der Übungssequenz:
wait "$stubborn_pid" 2>/dev/null || true
ps -p "$stubborn_pid" || echo "labex-stubborn required SIGKILL"
SIGKILL gibt einem Prozess keine Möglichkeit, seinen Zustand zu speichern oder Anwendungsressourcen sauber freizugeben. Deshalb sollte es nur als letztes Mittel eingesetzt werden.
kill richtet sich an eine bekannte PID. Wenn Sie einen Prozess anhand seines Namens oder seiner vollständigen Befehlszeile auswählen müssen, verbindet pkill die Suche mit dem Senden eines Signals. Starten Sie einen weiteren kontrollierten Prozess mit einer eindeutigen Befehlszeile:
bash -c 'exec -a labex-helper sleep 300' &
helper_pid=$!
echo "$helper_pid" > helper.pid
Prüfen Sie vor dem Eingriff die exakte Übereinstimmung der vollständigen Befehlszeile:
pgrep -af '^labex-helper 300$'
Senden Sie mit pkill -f SIGTERM an genau diese Übereinstimmung. Die Anker ^ und $ verhindern, dass das Übungsmuster auf andere Befehlszeilen passt:
pkill -TERM -f '^labex-helper 300$'
wait "$helper_pid" 2>/dev/null || true
ps -p "$helper_pid" || echo "labex-helper stopped by pkill"
Verwenden Sie präzise pkill-Muster und prüfen Sie Treffer zuerst mit pgrep; ein zu allgemeines Muster kann mehr Prozesse als beabsichtigt beenden.
Jobs im Vorder- und Hintergrund steuern
In diesem Schritt halten Sie einen Vordergrundbefehl an, setzen ihn im Hintergrund fort, holen ihn wieder in den Vordergrund und unterbrechen ihn.
Die Jobsteuerung gehört zur aktuell verwendeten interaktiven Shell. Starten Sie einen Vordergrundprozess mit einem eindeutig erkennbaren Namen:
cd /home/labex/project/process-lab
bash -c 'exec -a labex-job sleep 300'
Das Terminal ist nun durch den Vordergrundprozess belegt. Drücken Sie Ctrl+Z. Die Shell sendet ein Stoppsignal und zeigt wieder die Eingabeaufforderung an.
Listen Sie die dieser Shell bekannten Jobs auf. Die Option -l enthält auch die Prozess-ID:
jobs -l
Sie sollten einen Job mit dem Zustand Stopped sehen. Setzen Sie Job Nummer 1 im Hintergrund fort:
bg %1
jobs -l
Der Zustand sollte nun Running lauten, und die Eingabeaufforderung bleibt verfügbar. Holen Sie den Job wieder in den Vordergrund:
fg %1
Drücken Sie Ctrl+C, um ein Unterbrechungssignal an den Vordergrundjob zu senden. Die Eingabeaufforderung sollte wieder erscheinen. Vergewissern Sie sich, dass kein Übungsjob mehr vorhanden ist:
pgrep -af labex-job || echo "No labex-job process remains"
Erstellen Sie nach Abschluss der interaktiven Sequenz eine Abschlussmarkierung:
touch job-control.done
Verwenden Sie die Jobsteuerung für Befehle, die an das aktuelle Terminal gebunden sind. Später verwenden Sie nohup für Aufgaben, die nicht von der Terminalsitzung abhängen sollen.
Exit-Status auswerten und losgelöste Aufgaben ausführen
In diesem Schritt werten Sie den Exit-Status von Befehlen aus und führen eine kurze Hintergrundaufgabe aus, deren Ausgabe unabhängig von der Terminalanzeige erhalten bleibt.
Jeder Befehl gibt einen ganzzahligen Status zurück. Null bedeutet Erfolg; ein Wert ungleich null weist auf irgendeine Art von Fehler hin. Die Shell-Variable $? enthält den Status des zuletzt abgeschlossenen Befehls.
Führen Sie einen erfolgreichen Befehl aus und geben Sie unmittelbar danach seinen Status aus:
cd /home/labex/project/process-lab
true
echo "true status: $?"
Das Ergebnis ist 0. Führen Sie nun einen Befehl aus, der den angegebenen Pfad nicht finden kann:
ls missing-path
Sichern Sie den Status, bevor ein weiterer Befehl $? überschreibt:
missing_status=$?
echo "missing-path status: $missing_status"
Der Wert ist ungleich null. Speichern Sie beide erwarteten Bedeutungen:
printf 'success=0\nfailure=%s\n' "$missing_status" > exit-status.txt
Der Befehl nohup sorgt dafür, dass ein Programm das Auflegen-Signal des Terminals ignoriert. Das abschließende & startet es im Hintergrund. Die Umleitung < /dev/null trennt die Standardeingabe vom Terminal, während > nohup.log 2>&1 beide Ausgabeströme in eine Protokolldatei schreibt:
nohup bash -c 'for item in one two three; do echo "background: $item"; sleep 1; done' < /dev/null > nohup.log 2>&1 &
Speichern Sie die PID des Hintergrundprozesses und warten Sie, bis die kurze Aufgabe abgeschlossen ist:
echo $! > nohup.pid
sleep 4
cat nohup.log
Sie sollten drei Zeilen sehen, von background: one bis background: three. Bei länger laufenden Aufgaben bieten die gespeicherte PID und das Protokoll Möglichkeiten, den Fortschritt zu überprüfen.
Aktuelle Kernelmeldungen untersuchen
In diesem Schritt untersuchen Sie den Nachrichtenpuffer des Kernels und speichern die laufende Kernelversion als stabile Referenz.
Der Kernel protokolliert Meldungen zu Systemstart, Hardware, Treibern und Laufzeitereignissen in einem Ringpuffer. dmesg liest diesen Puffer aus. Dafür sind üblicherweise administrative Rechte erforderlich:
cd /home/labex/project/process-lab
sudo dmesg | tail -n 10
Die genauen Meldungen unterscheiden sich je nach Rechner und Zeitpunkt. Achten Sie auf das zeitstempelähnliche Feld sowie auf die Komponente oder das Subsystem, das die jeweilige Meldung erzeugt hat.
Mit der Option --level können Sie nach Schweregrad filtern. Zeigen Sie aktuelle Warnungen und Fehler an:
sudo dmesg --level=err,warn | tail -n 10
Keine Ausgabe bedeutet nicht, dass der Befehl fehlgeschlagen ist. Es kann lediglich bedeuten, dass der aktuelle Puffer keine Meldungen dieser Schweregrade enthält. Suchen Sie in den aktuellen Meldungen nach häufigen Begriffen aus den Bereichen Speicher und Netzwerk:
sudo dmesg | grep -Ei 'disk|filesystem|network|eth' | tail -n 10
Auch hier hängen die Ergebnisse vom aktuellen System ab. Speichern Sie die von uname -r gemeldete Kernelversion:
uname -r > kernel-version.txt
cat kernel-version.txt
Kernelmeldungen sind Hinweise und keine automatischen Diagnosen. Beziehen Sie sie gemeinsam mit Prozesszuständen, Dienstprotokollen und beobachteten Symptomen in Ihre Bewertung ein, bevor Sie eine Maßnahme ergreifen.
Zusammenfassung
Sie haben ein Linux-System identifiziert, Laufzeit und Load Averages interpretiert und Prozess-IDs, übergeordnete Prozesse, Besitzer, Zustände sowie Ressourcenmomentaufnahmen untersucht. Sie haben einen benannten Prozess gestartet und gefunden, SIGTERM vor SIGKILL verwendet und die Jobsteuerung im Vorder- und Hintergrund geübt.
Außerdem haben Sie Exit-Status ausgewertet, mit nohup und einer expliziten Protokollierung losgelöste Aufgaben ausgeführt und Kernelmeldungen mit dmesg untersucht. Diese auf Beobachtung ausgerichteten Vorgehensweisen bilden die Grundlage für eine sichere Fehlersuche bei Prozessen und bereiten Sie auf spätere Diagnosen zu Diensten, Protokollen und Netzwerken vor.



