Bash · Systemdiagnose · Linux · DevOps
Systemdiagnose mit ps, top, ss, lsof, journalctl
und Bash-Helfern für die Produktionsumgebung

Wenn ein Produktionssystem unerwartetes Verhalten zeigt, entscheidet die Qualität der Diagnose-Werkzeuge über Minuten oder Stunden Ausfallzeit. ps, top, ss, lsof und journalctl liefern zusammen ein vollständiges Bild – vorausgesetzt, man kennt die richtigen Flags und kombiniert sie zu gezielten Bash-Helfern.

18 Min. Lesezeit ps · top · ss · lsof · journalctl · Prozessanalyse · Speicher Linux · Bash 4.x · 5.x

1. Warum strukturierte Systemdiagnose entscheidend ist

Eine gute Systemdiagnose beginnt nicht mit dem Raten, sondern mit systematischer Datenerhebung. Jedes Linux-Produktionssystem stellt eine vollständige Informationsinfrastruktur bereit: das Proc-Filesystem, Systemd-Journal, Netzwerk-Stack-Statistiken und Dateideskriptor-Tabellen. Die Herausforderung liegt darin, diese Informationsquellen schnell und gezielt abzurufen, bevor der Druck einer laufenden Störung die Konzentration beeinträchtigt.

Vorgefertigte Bash-Helfer für die Systemdiagnose lösen genau dieses Problem: Statt unter Stress die richtigen Flags für ps, ss und lsof zu rekonstruieren, ruft man ein vorbereitetes Skript auf, das in 30 Sekunden ein vollständiges Diagnosebild liefert. Diese Helfer sollten auf jedem Produktionsserver im /usr/local/bin liegen und jederzeit ohne Root-Rechte ausführbar sein. Die folgenden Abschnitte zeigen, wie die wichtigsten Werkzeuge effektiv eingesetzt werden.

Die Systemdiagnose gliedert sich in vier Domänen: Prozesse (was läuft, wie viele Ressourcen verbraucht es), Netzwerk (welche Verbindungen bestehen, welche Ports lauschen), Speicher (wie viel wird wofür verwendet, gibt es Leaks) und Kernel/Journal (was hat das System protokolliert, gab es OOM-Kills oder Hardware-Fehler). Jede Domäne hat ihre eigenen Werkzeuge, die in Bash kombiniert werden können.

2. ps: Prozessanalyse jenseits von ps aux

ps aux ist der meistbekannte Befehl für die Systemdiagnose auf Prozessebene, aber weit von seinem vollen Potenzial entfernt. Mit ps -eo pid,ppid,user,pcpu,pmem,vsz,rss,stat,start,time,cmd --sort=-pcpu bekommt man eine nach CPU-Verbrauch sortierte Prozessliste mit Parent-PID, Speicherverbrauch in Kilobytes und dem exakten Befehlspfad. Das -o-Format ist der Schlüssel zur gezielten Systemdiagnose: Es ermöglicht, exakt die Spalten auszuwählen, die für die aktuelle Fragestellung relevant sind.

Für die Diagnose von Prozessbäumen in der Systemdiagnose ist ps --forest unersetzlich: Es zeigt die Eltern-Kind-Beziehungen aller Prozesse als ASCII-Baum und macht sofort sichtbar, welche Prozesse als Zombies hängen (Z-Status) oder unerwartete Kindprozesse spawnen. pstree -p ist eine Alternative mit kompakterer Darstellung. Für die Analyse eines einzelnen Prozesses liefert cat /proc/PID/status detaillierte Informationen wie Speichergrenzen, Namespaces und Capabilities, die ps nicht zeigt.


#!/usr/bin/env bash
# proc-diag.sh — Process analysis helper for system diagnosis
set -euo pipefail

TOP_N="${1:-10}"

echo "=== Top $TOP_N CPU consumers ==="
ps -eo pid,user,pcpu,pmem,rss,vsz,cmd --sort=-pcpu | head -n $(( TOP_N + 1 ))

echo ""
echo "=== Top $TOP_N Memory consumers (by RSS) ==="
ps -eo pid,user,pcpu,pmem,rss,cmd --sort=-rss | head -n $(( TOP_N + 1 ))

echo ""
echo "=== Zombie processes ==="
zombies=$(ps -eo stat,pid,ppid,cmd | awk '$1 ~ /^Z/ {print}')
if [[ -n "$zombies" ]]; then
  echo "$zombies"
else
  echo "No zombie processes found."
fi

echo ""
echo "=== Thread counts per process (top 5) ==="
# /proc/<pid>/status contains Threads: field
for pid_dir in /proc/[0-9]*/; do
  pid="${pid_dir//[^0-9]/}"
  [[ -f "$pid_dir/status" ]] || continue
  threads=$(grep -m1 '^Threads:' "$pid_dir/status" 2>/dev/null | awk '{print $2}')
  name=$(grep -m1 '^Name:' "$pid_dir/status" 2>/dev/null | awk '{print $2}')
  echo "$threads $pid $name"
done 2>/dev/null | sort -rn | head -5

3. top und htop: Ressourcen in Echtzeit beobachten

top ist für die interaktive Systemdiagnose unverzichtbar, aber seine nicht-interaktive Verwendung in Bash-Skripten wird oft übersehen. Mit top -b -n 1 (batch-Modus, ein Durchlauf) gibt top einen vollständigen Snapshot der aktuellen Ressourcenverteilung aus – ideal für Diagnoseskripte, die Systemzustände in einer Datei protokollieren. top -b -n 3 -d 2 macht drei Messungen im Abstand von 2 Sekunden und gibt den Durchschnitt aus, der aussagekräftiger als ein einzelner Snapshot ist.

Für automatisierte Systemdiagnose in Bash ist /proc/loadavg direkter als top: Die Datei enthält die 1-, 5- und 15-Minuten-Lastdurchschnitte, die Anzahl der laufenden Prozesse und die letzte PID. Das Lesen dieser Datei ist wesentlich effizienter als das Parsen von top-Ausgaben. Dasselbe gilt für CPU-Statistiken: /proc/stat enthält Rohwerte für alle CPU-Zustände (user, nice, system, idle, iowait, irq, softirq, steal), aus denen sich mit zwei aufeinanderfolgenden Messungen die exakte CPU-Auslastung berechnen lässt – ohne externe Tools.

4. ss: Netzwerk-Diagnose statt veraltetes netstat

ss (Socket Statistics) ist der Nachfolger von netstat und für die Systemdiagnose auf Netzwerkebene erheblich schneller und aussagekräftiger. Während netstat auf /proc/net/tcp und verwandten Dateien basiert, liest ss direkt über Netlink-Sockets aus dem Kernel – ohne die Limitierungen und Parsingfehler der Textdateien. Auf Systemen mit tausenden offenen Verbindungen ist der Unterschied messbar: netstat -an kann mehrere Sekunden dauern, ss -an liefert das Ergebnis in Millisekunden.

Für die Systemdiagnose auf Verbindungsebene sind die ss-Filter mächtig: ss -tp state established '( dport = :443 or dport = :80 )' zeigt alle etablierten HTTP/HTTPS-Verbindungen mit der zugehörigen PID und dem Prozessnamen. ss -lnp --filter "sport = :8080" prüft, welcher Prozess auf Port 8080 lauscht. Das -e-Flag zeigt erweiterte Socket-Informationen wie Timer, UID und Inode-Nummer. Der Befehl ss -s liefert eine kompakte Statistik-Zusammenfassung aller Socket-Typen.


#!/usr/bin/env bash
# net-diag.sh — Network diagnosis helper using ss and /proc
set -euo pipefail

echo "=== Listening ports with process names ==="
ss -lntp | awk 'NR==1 || $1=="LISTEN"'

echo ""
echo "=== Established connections summary ==="
ss -tn state established | awk 'NR>1 {print $4}' \
  | sed 's/:[0-9]*$//' \
  | sort | uniq -c | sort -rn | head -10

echo ""
echo "=== Connection state counts ==="
ss -tan | awk 'NR>1 {states[$1]++} END {for (s in states) printf "%6d %s\n", states[s], s}' \
  | sort -rn

echo ""
echo "=== TIME_WAIT connections (potential exhaustion risk) ==="
tw_count=$(ss -tan state time-wait | wc -l)
echo "TIME_WAIT sockets: $tw_count"
if (( tw_count > 1000 )); then
  echo "[WARN] High TIME_WAIT count — check net.ipv4.tcp_tw_reuse" >&2
fi

echo ""
echo "=== UDP socket usage ==="
ss -uanp | head -20

5. lsof: offene Dateien, Sockets und Dateideskriptoren

lsof (List Open Files) ist das umfassendste Werkzeug für die Systemdiagnose auf Ressourcenebene. In Linux ist fast alles eine Datei – reguläre Dateien, Sockets, Pipes, Devices und Pseudodateien in /proc. lsof kann all diese aufzählen und nach Prozess, User, Dateiname oder Protokoll filtern. lsof -p PID zeigt alle offenen Ressourcen eines Prozesses und ist die erste Anlaufstelle, wenn ein Prozess sich unerwartet verhält, Dateien nicht schließt oder Speicher leckt.

Für die Systemdiagnose bei Festplattenplatz-Problemen ist lsof +L1 ein unverzichtbares Werkzeug: Es zeigt alle Dateien, die gelöscht wurden, aber noch von einem Prozess offen gehalten werden. Das ist der klassische Fall, wenn df keinen freien Platz zeigt, du / aber erheblich weniger Platz beansprucht als erwartet – zwischen den beiden liegt der Platz der gelöschten, aber noch referenzierten Dateien. lsof -i :PORT zeigt, welcher Prozess einen bestimmten Port belegt, ohne Root-Rechte zu benötigen.

6. journalctl: Kernel-Logs und Systemd-Units gezielt auswerten

journalctl ist für die Systemdiagnose auf Systemd-Systemen das zentrale Log-Werkzeug. Es kombiniert Kernel-Logs (dmesg), Systemd-Unit-Logs und Anwendungs-Logs in einem einzigen strukturierten Journal. journalctl -k zeigt nur Kernel-Nachrichten – äquivalent zu dmesg, aber mit korrekten Zeitstempeln relativ zum Systemstart. Für OOM-Diagnose ist journalctl -k | grep -i 'oom\|kill' der erste Befehl: Wenn der Kernel Prozesse wegen Speichermangel beendet hat, steht es hier.

Die zeitbasierte Filterung in journalctl ist für strukturierte Systemdiagnose mächtig: journalctl --since "2026-05-09 10:00" --until "2026-05-09 11:00" -p err zeigt alle Fehler in einem Zeitfenster. -p err filtert auf Priorität Error und höher (err, crit, alert, emerg). Das --output json-Format gibt strukturierte JSON-Ausgabe, die mit jq weiterverarbeitet werden kann. Für die Systemdiagnose nach einem Neustart zeigt journalctl -b -1 das Journal des vorherigen Boots.


#!/usr/bin/env bash
# system-health.sh — Combined system diagnosis snapshot
set -euo pipefail

SINCE="${1:-1 hour ago}"
OUTPUT_DIR="${2:-/tmp/diag-$(date +%Y%m%d-%H%M%S)}"

mkdir -p "$OUTPUT_DIR"

echo "[INFO] Running system diagnosis snapshot to $OUTPUT_DIR"

# Process snapshot
ps -eo pid,ppid,user,pcpu,pmem,rss,stat,cmd --sort=-rss > "$OUTPUT_DIR/processes.txt"

# Network connections
ss -tanp > "$OUTPUT_DIR/sockets.txt"
ss -s    > "$OUTPUT_DIR/socket-stats.txt"

# Kernel messages since given time
journalctl -k --since "$SINCE" > "$OUTPUT_DIR/kernel-log.txt"

# Errors from all units
journalctl --since "$SINCE" -p err --no-pager > "$OUTPUT_DIR/errors.txt"

# OOM and kill events
journalctl -k --since "$SINCE" | grep -iE 'oom|killed|segfault' \
  > "$OUTPUT_DIR/oom-events.txt" || true

# Memory breakdown
cat /proc/meminfo > "$OUTPUT_DIR/meminfo.txt"

# Disk usage of open but deleted files
lsof +L1 2>/dev/null | awk 'NR==1 || $7 < 1' > "$OUTPUT_DIR/deleted-open-files.txt" || true

echo "[INFO] Diagnosis complete. Archive with:"
echo "  tar czf diag-$(date +%Y%m%d).tar.gz -C $(dirname $OUTPUT_DIR) $(basename $OUTPUT_DIR)"

7. Speicher-Checks: /proc/meminfo, free und smaps

Die Systemdiagnose für Speicherproblem beginnt mit free -h, das einen groben Überblick gibt. Für detaillierte Analyse liefert /proc/meminfo die Rohwerte: MemAvailable ist der relevante Wert für die tatsächlich verfügbare Speichermenge – er berücksichtigt Caches und Puffer, die vom Kernel bei Bedarf freigegeben werden. MemFree allein ist irreführend: Ein System mit wenig MemFree, aber hohem MemAvailable ist nicht unter Speicherdruck.

Für die Systemdiagnose eines einzelnen Prozesses auf Memory-Leaks ist /proc/PID/smaps die detaillierteste Quelle. smaps_rollup fasst alle Memory-Map-Einträge zusammen und zeigt Private_Dirty – den tatsächlich verbrauchten privaten Speicher, der nicht mit anderen Prozessen geteilt wird. Wächst dieser Wert kontinuierlich, ist das ein starkes Indiz für ein Memory-Leak. Das Skript smem oder ein eigener Bash-Helfer kann diese Werte über Zeit aufzeichnen und Trends erkennen.

8. Bash-Helfer: Diagnoseskripte für den Ernstfall

Der Wert von Bash-Helfern für die Systemdiagnose liegt in ihrer Vorbereitung: Im Ernstfall muss man keine Flags nachschlagen, sondern ruft ein vorbereitetes Skript auf. Das wichtigste dieser Skripte ist das "Runbook-Skript" – ein Bash-Skript, das in einer bestimmten Reihenfolge alle relevanten Diagnoseinformationen sammelt und in einer komprimierten Datei ablegt. So kann man im Notfall in 30 Sekunden eine vollständige Systemaufnahme machen, bevor ein Neustart oder eine Änderung den Zustand überschreibt.

Ein zweiter wichtiger Bash-Helfer für die Systemdiagnose ist das Trend-Skript: Es läuft im Hintergrund und schreibt jede Minute CPU, Speicher, Verbindungszahl und Festplatten-I/O in eine CSV-Datei. Wenn eine Störung auftritt, hat man retrospektiv Daten aus den letzten Stunden und kann den Zeitpunkt der Verschlechterung exakt bestimmen. Kombiniert mit journalctl-Filtern für denselben Zeitraum entsteht ein vollständiges Bild der Systemdiagnose ohne externe Monitoring-Infrastruktur.

9. Systemdiagnose-Werkzeuge im direkten Vergleich

Die vier Domänen der Systemdiagnose erfordern unterschiedliche Werkzeuge. Die folgende Tabelle zeigt, welches Tool für welche Fragestellung die erste Wahl ist.

Fragestellung Erstes Werkzeug Tiefere Analyse Hinweis
Welcher Prozess verbraucht CPU? top / ps --sort=-pcpu /proc/PID/stat Mehrere Messungen mitteln
Wer belegt Port X? ss -lntp lsof -i :PORT ss ist schneller als lsof
Gelöschte Datei belegt Platz? lsof +L1 /proc/PID/fd/ Ohne Root nur eigene Prozesse
OOM-Kill aufgetreten? journalctl -k | grep oom /proc/PID/oom_score Zeitstempel des letzten Boots
Memory-Leak in Prozess? ps --sort=-rss /proc/PID/smaps_rollup Private_Dirty über Zeit prüfen

Die Systemdiagnose wird effizienter, wenn man die Werkzeuge in Bash-Funktionen kapselt, die unter sprechenden Namen abrufbar sind. Ein Alias wie alias who-uses-port='ss -lntp | grep' oder eine Funktion proc-mem() { cat /proc/"$1"/smaps_rollup; } reduziert die kognitive Last im Ernstfall. Solche Alias- und Funktions-Bibliotheken gehören in die ~/.bashrc oder eine dedizierte ~/.bash_diag-Datei, die auf allen Produktionsservern vorhanden ist.

Mironsoft

Systemdiagnose, Incident-Response und DevOps-Infrastruktur

Systemdiagnose-Skripte für eure Produktion?

Wir erstellen maßgeschneiderte Bash-Helfer für eure Infrastruktur – von der Runbook-Automatisierung bis zu Trend-Skripten, die im Hintergrund laufen und im Incident die richtigen Daten liefern.

Runbook-Skripte

Systemdiagnose-Snapshots in 30 Sekunden – ps, ss, lsof, journalctl kombiniert

Trend-Monitoring

Ressourcen-Trends aufzeichnen und Anomalien retrospektiv nachvollziehen

Incident-Playbooks

Standardisierte Diagnose-Abläufe für OOM, hohe Last und Netzwerkprobleme

10. Zusammenfassung

Strukturierte Systemdiagnose mit ps, top, ss, lsof und journalctl liefert in Minuten ein vollständiges Bild des Systemzustands. ps -eo mit angepassten Formaten ist flexibler als ps aux. ss ist schneller und präziser als netstat und bietet mächtige Filter für Verbindungsanalyse. lsof +L1 findet gelöschte Dateien, die noch Plattenplatz belegen. journalctl -k zeigt Kernel-Meldungen mit korrekten Zeitstempeln. /proc/PID/smaps_rollup liefert den tatsächlichen privaten Speicherverbrauch für Memory-Leak-Diagnose.

Der entscheidende Multiplikator der Systemdiagnose ist die Vorbereitung: Bash-Helfer, die im Ernstfall sofort einsatzbereit sind, reduzieren Reaktionszeiten drastisch. Ein Runbook-Skript, das in 30 Sekunden alle relevanten Daten sammelt, ist wertvoller als jedes Monitoring-Dashboard, wenn ein Server unter Last kaum erreichbar ist. Diese Helfer sollten versioniert, auf allen Servern verfügbar und regelmäßig getestet werden.

Systemdiagnose — Das Wichtigste auf einen Blick

Prozessanalyse

ps -eo pid,user,pcpu,rss,cmd --sort=-rss – nach Bedarf sortieren, --forest für Prozessbaum und Zombie-Erkennung.

Netzwerk-Diagnose

ss -lntp für lauschende Ports, ss -tan für Verbindungsstatus-Zählungen. Schneller und präziser als netstat.

Platz und Dateideskriptoren

lsof +L1 für gelöschte, noch offene Dateien. lsof -p PID für alle Ressourcen eines Prozesses.

Kernel und OOM

journalctl -k | grep -i oom für OOM-Kills. -b -1 für letzten Boot. -p err für alle Fehler.

11. FAQ: Systemdiagnose mit ps, top, ss, lsof, journalctl und Bash-Helfern

1Unterschied ss vs. netstat?
ss liest über Netlink direkt aus dem Kernel – deutlich schneller als netstat mit /proc/net/tcp-Parsing. Mächtigere Filter, genauere Informationen.
2df zeigt kein Platz, du aber schon?
lsof +L1: gelöschte Dateien, die noch offen sind. Kernel gibt Platz erst frei wenn letzter Dateideskriptor geschlossen wird. Prozess neustarten befreit den Platz.
3OOM-Kills erkennen?
journalctl -k | grep -i oom. Für vorherigen Boot: -b -1. Enthält Prozessname, PID und oom_score zum Zeitpunkt des Kills.
4smaps_rollup für Memory-Leak?
Private_Dirty ist der tatsächliche private Speicher. Wächst dieser Wert kontinuierlich → Memory-Leak. RES in top zeigt shared Memory mit – weniger aussagekräftig.
5Zombie-Prozesse finden?
ps -eo stat,pid,ppid,cmd | awk '$1 ~ /^Z/'. Zombies belegen nur Prozesstabelleneintrag, keinen Speicher. Elternprozess muss wait() aufrufen.
6MemAvailable vs. MemFree?
MemAvailable = MemFree + freigebbare Caches. Relevanter Wert für Speicherdruck. MemFree allein auf gecachten Systemen immer niedrig — irreführend.
7Port-Belegung ohne Root prüfen?
ss -lntp zeigt eigene Prozesse auch ohne Root. Für alle Prozesse braucht man Root. lsof -i :PORT als Alternative.
8journalctl auf Zeitraum filtern?
--since und --until mit absolutem Timestamp oder relative Angabe wie "1 hour ago". -p err für Fehler-Priorität und höher.
9Bester Snapshot-Helfer?
Runbook-Skript: ps, ss, lsof +L1, journalctl -k, meminfo in Verzeichnis schreiben und tar.gz archivieren. 30 Sekunden, bevor Neustart den Zustand überschreibt.
10Ressourcen-Trends ohne Monitoring?
Bash-Skript mit cron: /proc/loadavg, /proc/meminfo und ss -s jede Minute in CSV schreiben. Im Incident den Zeitraum der Störung herausfiltern.