Farben, Progress, Tabellen und Prompts
Shell-Skripte, die den Operator informieren statt zu verwirren, sind wartbarer, sicherer und angenehmer zu bedienen. Mit tput, ANSI-Codes, Spinners, column und printf-Tabellen entsteht professionelle CLI-UX ohne externe Abhängigkeiten — direkt in Bash, portabel und robustheitsorientiert.
Inhaltsverzeichnis
- 1. Warum CLI-UX in Bash wichtig ist
- 2. tput: Terminal-Fähigkeiten portabel nutzen
- 3. ANSI-Escape-Codes: Farbe und Formatierung
- 4. Spinner und Fortschrittsbalken
- 5. Strukturierte Ausgabe mit column und printf
- 6. Interaktive Prompts: read, select und Bestätigungen
- 7. Log-Level-Ausgaben mit Farbe und Kontext
- 8. TTY-Erkennung und nicht-interaktiver Modus
- 9. CLI-UX-Techniken im Vergleich
- 10. Zusammenfassung
- 11. FAQ
1. Warum CLI-UX in Bash wichtig ist
Der Begriff CLI-UX in Bash klingt zunächst nach einem Widerspruch: Shell-Skripte gelten als reine Werkzeuge für Entwickler und Systemadministratoren, die mit rohem Text umgehen können. Doch in der Praxis laufen Deployment-Skripte, Backup-Routinen und Maintenance-Tools in Situationen, in denen schnelle Lesbarkeit über Fehler entscheidet. Wenn ein Deploy-Skript nach 40 Minuten mit einem einzeiligen Fehlertext abbricht, der in einer Wand aus gleichwertig aussehenden Zeilen untergeht, kostet das Zeit — manchmal erheblich.
Professionelle CLI-UX in Bash bedeutet nicht, ein vollwertiges UI in die Shell zu bringen. Es geht darum, Status und Fehler visuell eindeutig zu machen, den Operator über den aktuellen Fortschritt zu informieren, Tabellen lesbar zu halten und Entscheidungsaufforderungen klar zu formulieren. Das sind pragmatische Verbesserungen mit überschaubarem Aufwand, die den Betrieb von Shell-Skripten spürbar verbessern. Alle beschriebenen Techniken funktionieren ohne externe Abhängigkeiten — mit tput, ANSI-Codes, den Bash-Builtins read und select sowie den Standard-Tools printf und column.
Die wichtigste Grundregel für CLI-UX in Bash: Statusmeldungen gehören auf stderr (>&2), Ergebnisdaten auf stdout. Das ermöglicht die Weiterverarbeitung in Pipes, ohne dass Fortschrittsausgaben das Ergebnis verunreinigen. Spinner und Fortschrittsbalken müssen vor der finalen Ausgabe gelöscht werden. Farben dürfen nur dann ausgegeben werden, wenn das Terminal sie unterstützt — nie in Pipe-Kontexten oder wenn die Ausgabe in eine Datei umgeleitet wird.
2. tput: Terminal-Fähigkeiten portabel nutzen
tput ist das portable Interface zur Terminfo-Datenbank und die empfohlene Methode für CLI-UX in Bash, wenn Kompatibilität über verschiedene Terminalemulatoren hinweg wichtig ist. Statt hardcodierte ANSI-Codes zu verwenden, fragt tput zur Laufzeit ab, welche Sequenzen das aktuelle Terminal unterstützt. Das ist besonders relevant für Skripte, die auf verschiedenen Systemen laufen — von modernen Linux-Servern mit xterm-256color über einfache SSH-Sessions mit TERM=dumb bis zu CI-Umgebungen ohne Terminal.
Die wichtigsten tput-Kommandos für CLI-UX in Bash: tput bold aktiviert Fettschrift, tput sgr0 setzt alle Attribute zurück, tput setaf N setzt die Vordergrundfarbe (0–7 für Standard, 0–255 für 256-Farben), tput setab N die Hintergrundfarbe. Für Positionierung: tput cup ROW COL setzt den Cursor, tput el löscht bis zum Zeilenende, tput civis und tput cnorm verstecken und zeigen den Cursor. Diese Befehle sind die Bausteine für Spinner, die eine Zeile überschreiben, ohne die Ausgabe zu vermehren.
Ein kritischer Aspekt für robuste CLI-UX in Bash: tput schreibt auf stdout. Wenn man tput-Ausgaben in Variablen speichert und diese dann über >&2 ausgibt, muss man sicherstellen, dass das Redirect auf stderr das Terminal tatsächlich erreicht. Für CI-Umgebungen mit TERM=dumb oder ohne Terminal gibt tput leere Strings zurück — die Skriptausgabe bleibt plain-text, ohne Fehler. Das macht tput zur bevorzugten Wahl gegenüber direkten ANSI-Sequenzen für langfristig wartbare Skripte.
#!/usr/bin/env bash
# lib/colors.sh — Portable terminal color library using tput
set -euo pipefail
# Initialize colors only if terminal supports them
setup_colors() {
if [[ -t 2 ]] && [[ -n "${TERM:-}" ]] && tput colors &>/dev/null 2>&1; then
readonly RED="$(tput setaf 1)"
readonly GREEN="$(tput setaf 2)"
readonly YELLOW="$(tput setaf 3)"
readonly BLUE="$(tput setaf 4)"
readonly CYAN="$(tput setaf 6)"
readonly BOLD="$(tput bold)"
readonly DIM="$(tput dim 2>/dev/null || true)"
readonly RESET="$(tput sgr0)"
readonly CURSOR_HIDE="$(tput civis 2>/dev/null || true)"
readonly CURSOR_SHOW="$(tput cnorm 2>/dev/null || true)"
readonly ERASE_LINE="$(tput el)"
else
# Fallback for non-interactive or dumb terminals
readonly RED="" GREEN="" YELLOW="" BLUE="" CYAN=""
readonly BOLD="" DIM="" RESET=""
readonly CURSOR_HIDE="" CURSOR_SHOW="" ERASE_LINE=""
fi
}
# Usage helper functions
info() { printf '%s[INFO]%s %s\n' "${CYAN}" "${RESET}" "$*" >&2; }
ok() { printf '%s[OK]%s %s\n' "${GREEN}" "${RESET}" "$*" >&2; }
warn() { printf '%s[WARN]%s %s\n' "${YELLOW}" "${RESET}" "$*" >&2; }
error() { printf '%s[ERROR]%s %s\n' "${RED}" "${RESET}" "$*" >&2; }
bold_msg(){ printf '%s%s%s\n' "${BOLD}" "$*" "${RESET}" >&2; }
setup_colors
info "Deployment gestartet"
ok "Datenbank migriert"
warn "Legacy-Konfiguration gefunden"
error "Verbindung fehlgeschlagen"
3. ANSI-Escape-Codes: Farbe und Formatierung
Wo tput nicht verfügbar ist oder direkte Kontrolle benötigt wird, bieten ANSI-Escape-Codes präzise Möglichkeiten für CLI-UX in Bash. Die grundlegende Syntax lautet \e[Nm oder \033[Nm für Farben und Attribute. Die wichtigsten Codes: \e[0m für Reset, \e[1m für Bold, \e[2m für Dim, \e[31m bis \e[37m für Standardfarben und \e[38;5;Nm für 256-Farben-Modus. Für 24-Bit-Farben (True Color) lautet die Syntax \e[38;2;R;G;Bm — wird von den meisten modernen Terminals unterstützt.
Wichtig für zuverlässige CLI-UX in Bash: ANSI-Codes müssen immer mit einem Reset abgeschlossen werden, da sie andernfalls die gesamte nachfolgende Terminalausgabe färben. Das $'...' Quoting in Bash erlaubt Escape-Sequenzen direkt im String-Literal: $'\e[32m' statt des unlesbareren $(printf '\033[32m'). Für das Cursor-Positioning ist \e[ROW;COLf oder \e[ROW;COLH die direkte ANSI-Alternative zu tput cup. Mit \r (Carriage Return ohne Newline) kehrt der Cursor zum Zeilenanfang zurück, ohne eine neue Zeile zu beginnen — die Grundlage für überschreibbare Statuszeilen.
4. Spinner und Fortschrittsbalken
Ein Spinner in Bash ist eine der sichtbarsten Verbesserungen für CLI-UX bei lang laufenden Operationen. Er signalisiert dem Operator, dass das Skript aktiv arbeitet und nicht eingefroren ist. Die Implementierung nutzt den Carriage Return \r, um die aktuelle Zeile zu überschreiben, und eine Array-Sequenz von Unicode-Zeichen als Frame-Folge. Der Spinner läuft als Hintergrundprozess, während der eigentliche Befehl im Vordergrund ausgeführt wird — mit einem trap, der den Spinner bei Abschluss stoppt.
Fortschrittsbalken für bekannte Gesamtmengen folgen demselben Muster: Die Fortschritts-Funktion berechnet aus aktuellem Index und Gesamtanzahl den Prozentsatz und die Balkenlänge, schreibt die Zeile mit \r in den Anfang zurück und kann so live aktualisiert werden. Kritisch für stabile CLI-UX in Bash: Der Cursor muss versteckt werden, während der Fortschrittsbalken aktiv ist, und nach Abschluss wieder sichtbar gemacht werden — sonst wirkt die Ausgabe unfertig. Ein trap auf EXIT stellt sicher, dass der Cursor auch bei Fehlerabbruch wieder erscheint.
#!/usr/bin/env bash
set -euo pipefail
# Spinner running as background process
start_spinner() {
local message="${1:-Bitte warten…}"
local frames=('⠋' '⠙' '⠹' '⠸' '⠼' '⠴' '⠦' '⠧' '⠇' '⠏')
local i=0
printf '%s' "${CURSOR_HIDE:-}" >&2
while true; do
printf '\r%s %s ' "${frames[$((i % ${#frames[@]}))]}"] "$message" >&2
sleep 0.1
(( i++ ))
done
}
stop_spinner() {
local pid="${1:-}"
[[ -n "$pid" ]] && kill "$pid" 2>/dev/null || true
printf '\r%s\r' "${ERASE_LINE:-}" >&2
printf '%s' "${CURSOR_SHOW:-}" >&2
}
# Usage: wrap a long-running command
spinner_pid=""
trap 'stop_spinner "$spinner_pid"' EXIT
start_spinner "Deployment läuft…" &
spinner_pid=$!
sleep 3 # Replace with actual long-running operation
stop_spinner "$spinner_pid"
spinner_pid=""
printf '%s[OK]%s Deployment abgeschlossen\n' "${GREEN:-}" "${RESET:-}" >&2
# ---- Progress bar for known totals ----
progress_bar() {
local current=$1 total=$2 label="${3:-Fortschritt}"
local width=40
local pct=$(( current * 100 / total ))
local filled=$(( current * width / total ))
local bar
bar="$(printf '%*s' "$filled" '' | tr ' ' '█')$(printf '%*s' "$((width - filled))" '' | tr ' ' '░')"
printf '\r %s [%s] %3d%%' "$label" "$bar" "$pct" >&2
[[ $current -eq $total ]] && printf '\n' >&2
}
files=( /etc/*.conf )
total=${#files[@]}
for i in "${!files[@]}"; do
progress_bar "$(( i + 1 ))" "$total" "Konfigurationen prüfen"
sleep 0.05 # Simulate work
done
5. Strukturierte Ausgabe mit column und printf
Tabellarische Ausgaben sind ein zentrales Element professioneller CLI-UX in Bash. Das Tool column aus dem util-linux-Paket kann tabulatorseparierte Eingaben in ausgerichtete Spalten umwandeln. Mit column -t werden Spaltenbreiten automatisch berechnet, column -s $'\t' gibt das Trennzeichen an. Diese Methode ist für dynamische Daten geeignet, bei denen die Spaltenbreiten nicht im Voraus bekannt sind — etwa bei Dateilisten, Prozessauflistungen oder Konfigurationsübersichten.
Für vorhersagbare Tabellenformate ist printf mit Formatierungsangaben die präzisere Wahl. Die Formatspezifikation %-20s %10s %8s definiert linksbündige Felder mit fester Breite. Das ist die bevorzugte Technik für CLI-UX in Bash, wenn Tabellen einen festen Header haben und Zeilen programmatisch generiert werden — zum Beispiel in Deployment-Reports, Server-Status-Übersichten oder Kostenaufstellungen. Farbige Header durch ANSI-Codes oder tput machen den Unterschied zwischen einem reinen Textdump und einer lesbaren Statusübersicht.
Ein weiteres nützliches Werkzeug für CLI-UX in Bash ist die Kombination von printf mit \r für einzeilige, überschreibbare Statuszeilen. Statt jede Aktion in eine neue Zeile zu schreiben, aktualisiert man eine einzige Statuszeile — ähnlich wie Ansible oder Docker Compose ihre Ausgaben gestalten. Nach Abschluss wird die letzte Statuszeile durch eine kompakte Zusammenfassung ersetzt, sodass das Terminal nach einem langen Lauf übersichtlich bleibt.
#!/usr/bin/env bash
set -euo pipefail
# ---- column-based table with auto-width ----
print_service_table() {
local -a rows=()
rows+=("SERVICE\tSTATUS\tPORT\tUPTIME")
rows+=("nginx\trunning\t80,443\t14d 3h")
rows+=("mysql\trunning\t3306\t14d 3h")
rows+=("redis\tstopped\t6379\t—")
rows+=("php-fpm\trunning\t9000\t2d 11h")
printf '%s\n' "${rows[@]}" | column -t -s $'\t'
}
# ---- printf-based fixed-width table with colors ----
print_deploy_report() {
local sep="${BOLD:-}$(printf '%0.s─' {1..60})${RESET:-}"
printf '%s\n' "$sep" >&2
printf "${BOLD:-}%-28s %12s %10s %8s${RESET:-}\n" \
"SCHRITT" "STATUS" "DAUER" "CODE" >&2
printf '%s\n' "$sep" >&2
local -a steps=(
"Composer install|${GREEN:-}OK${RESET:-}|42s|0"
"DB-Migration|${GREEN:-}OK${RESET:-}|8s|0"
"Static Content|${YELLOW:-}WARN${RESET:-}|120s|0"
"Cache flush|${GREEN:-}OK${RESET:-}|2s|0"
"Smoke test|${RED:-}FAIL${RESET:-}|5s|1"
)
for step in "${steps[@]}"; do
IFS='|' read -r name status dur code <<< "$step"
printf "%-28s %12b %10s %8s\n" "$name" "$status" "$dur" "$code" >&2
done
printf '%s\n' "$sep" >&2
}
setup_colors() {
if [[ -t 2 ]]; then
RED="$(tput setaf 1)"; GREEN="$(tput setaf 2)"
YELLOW="$(tput setaf 3)"; BOLD="$(tput bold)"; RESET="$(tput sgr0)"
else
RED="" GREEN="" YELLOW="" BOLD="" RESET=""
fi
}
setup_colors
print_service_table
print_deploy_report
6. Interaktive Prompts: read, select und Bestätigungen
Interaktive Prompts gehören zur CLI-UX in Bash überall dort, wo ein Skript eine Entscheidung des Operators erfordert, bevor es mit einer potenziell irreversiblen Aktion fortfährt. Das Bash-Builtin read mit der Option -r -p "Prompt: " variable gibt eine Prompt-Nachricht aus und liest die Eingabe des Benutzers in eine Variable. Mit -t N kann ein Timeout gesetzt werden, nach dem automatisch ein Standardwert gilt. Mit -s wird die Eingabe verborgen — nützlich für Passwörter und Tokens.
Das Builtin select erstellt ein nummeriertes Menü aus einem Array von Optionen und wartet auf eine Auswahl. Es ist die sauberste Methode für CLI-UX in Bash, wenn der Benutzer aus einer festen Liste wählen soll — zum Beispiel zwischen Deployment-Umgebungen (dev, staging, prod) oder zwischen Rollback-Optionen. Eine häufige Erweiterung: Farbkodierung der Optionen und Validierung der Eingabe mit einer Schleife, die so lange wiederholt, bis eine gültige Auswahl getroffen wird.
7. Log-Level-Ausgaben mit Farbe und Kontext
Ein strukturiertes Log-Level-System ist eine der wirkungsvollsten Verbesserungen für CLI-UX in Bash. Statt unterschiedslosen echo-Aufrufen implementiert man eine Logging-Bibliothek mit den Levels DEBUG, INFO, WARN, ERROR und FATAL, die je nach konfiguriertem Log-Level ausgefiltert werden. Jedes Level hat eine feste Farbe: DEBUG grau/gedimmt, INFO cyan, WARN gelb, ERROR rot, FATAL bold-rot. Zeitstempel im ISO-8601-Format und der aufrufende Dateiname über ${BASH_SOURCE[1]} vervollständigen den Kontext.
Die Kombination von Farbe und strukturierten Feldern erlaubt es, in einem Terminal-Scrollen gezielt auf Fehler und Warnungen zu achten, ohne jede Zeile zu lesen. Für CLI-UX in Bash in Produktionsskripten gilt: Logging-Funktionen schreiben immer auf stderr, nie auf stdout. Das ermöglicht, das Skript in Pipes zu verwenden (./deploy.sh | jq .), ohne dass Log-Zeilen den JSON-Output verunreinigen. Mit LOG_LEVEL=${LOG_LEVEL:-INFO} kann das Level extern gesteuert werden — DEBUG bleibt still in Produktion und gesprächig beim Debuggen.
#!/usr/bin/env bash
# lib/logging.sh — Structured log-level output with colors
set -euo pipefail
declare -A LOG_LEVELS=([DEBUG]=0 [INFO]=1 [WARN]=2 [ERROR]=3 [FATAL]=4)
CURRENT_LOG_LEVEL="${LOG_LEVEL:-INFO}"
_log() {
local level="$1"; shift
local level_num="${LOG_LEVELS[$level]:-1}"
local current_num="${LOG_LEVELS[$CURRENT_LOG_LEVEL]:-1}"
[[ $level_num -lt $current_num ]] && return 0
local ts
ts="$(date '+%Y-%m-%dT%H:%M:%S')"
local caller="${BASH_SOURCE[2]##*/}:${BASH_LINENO[1]}"
local color=""
case "$level" in
DEBUG) color="${DIM:-}" ;;
INFO) color="${CYAN:-}" ;;
WARN) color="${YELLOW:-}" ;;
ERROR) color="${RED:-}" ;;
FATAL) color="${BOLD:-}${RED:-}" ;;
esac
printf '%s%s [%-5s] [%s] %s%s\n' \
"$color" "$ts" "$level" "$caller" "$*" "${RESET:-}" >&2
}
debug() { _log DEBUG "$@"; }
info() { _log INFO "$@"; }
warn() { _log WARN "$@"; }
error() { _log ERROR "$@"; }
fatal() { _log FATAL "$@"; exit 1; }
# Example usage
info "Deployment-Prozess gestartet für Umgebung: ${DEPLOY_ENV:-unknown}"
debug "Composer-Version: $(composer --version 2>/dev/null | head -1 || echo n/a)"
warn "Verzeichnis /tmp/deploy existiert bereits, wird überschrieben"
error "Datenbankverbindung fehlgeschlagen nach 3 Versuchen"
fatal "Kritischer Fehler: Rollback nicht möglich, manuelle Intervention erforderlich"
8. TTY-Erkennung und nicht-interaktiver Modus
Robuste CLI-UX in Bash muss zwischen interaktivem und nicht-interaktivem Modus unterscheiden. In CI-Pipelines, Cron-Jobs und Pipe-Kontexten darf ein Skript weder auf Benutzereingaben warten noch Farb-Codes ausgeben, die als Steuerzeichen in Logdateien erscheinen. Die Erkennung erfolgt über die Bash-Bedingung [[ -t 0 ]] (stdin ist ein Terminal), [[ -t 1 ]] (stdout) und [[ -t 2 ]] (stderr). Mit diesen Tests schaltet das Skript automatisch zwischen interaktivem Modus mit Farben und Prompts und nicht-interaktivem Modus mit Plain-Text-Logging um.
Die Variable $TERM gibt Auskunft über den Terminaltyp. TERM=dumb zeigt an, dass das Terminal keine Escape-Sequenzen versteht. Die Variable $CI, die von GitHub Actions, GitLab CI und anderen Systemen automatisch gesetzt wird, kann als zusätzlicher Indikator verwendet werden. Für CLI-UX in Bash gilt die Regel: Immer defensiv testen, nie davon ausgehen, dass ein Terminal vorhanden ist. Ein Skript, das im Terminal schön aussieht, aber im CI mit Escape-Sequenzen in Logdateien endet, hat eine schlechtere UX als eines ohne jegliche Formatierung.
9. CLI-UX-Techniken im Vergleich
Die verschiedenen Techniken für CLI-UX in Bash haben unterschiedliche Stärken und Einsatzbereiche. Die Wahl zwischen tput und direkten ANSI-Codes, zwischen column und printf-Tabellen oder zwischen interaktiven Prompts und Kommandozeilen-Flags hängt von den Anforderungen des jeweiligen Skripts ab.
| Technik | Einsatzbereich | Portabilität | Empfehlung |
|---|---|---|---|
| tput | Farben, Cursor-Kontrolle, Attribute | Hoch (Terminfo) | Bevorzugt für alle Terminal-Attribute |
| ANSI-Codes direkt | 24-Bit-Farben, präzise Kontrolle | Mittel (xterm/VTE) | Für moderne Terminals, mit TTY-Check |
| column -t | Dynamische Tabellen, variable Breiten | Hoch (util-linux) | Für Dateilisten und dynamische Daten |
| printf-Tabellen | Feste Reports, farbige Header | Sehr hoch (Bash-Builtin) | Für strukturierte Deployment-Reports |
| Spinner/Progress | Lang laufende Operationen | Terminal erforderlich | Mit TTY-Check und trap-Cleanup |
Für die meisten Skripte empfiehlt sich eine Library-Datei (lib/ui.sh), die alle UX-Funktionen zentralisiert. Die Library prüft bei Initialisierung die Terminal-Fähigkeiten, setzt Farbvariablen und exportiert Logging- und Fortschrittsfunktionen. Alle Skripte im Projekt laden dieselbe Library mit source "$(dirname "${BASH_SOURCE[0]}")/lib/ui.sh". Das eliminiert Code-Duplikation und stellt sicher, dass die CLI-UX in Bash über alle Skripte konsistent ist.
Mironsoft
Shell-Automatisierung, DevOps-Tooling und Deployment-Infrastruktur
Shell-Skripte, die den Operator wirklich informieren?
Wir entwickeln Bash-Skripte mit professioneller CLI-UX — strukturiertes Logging, Fortschrittsanzeigen, Tabellen und interaktive Prompts, die im Terminal übersichtlich und in CI-Pipelines problemlos funktionieren.
UI-Bibliotheken
Portable Farb-, Logging- und Progress-Bibliotheken für bestehende Bash-Projekte
Deploy-Berichte
Strukturierte tabellarische Ausgaben für Deployment-Protokolle und Status-Reports
CI-Kompatibilität
TTY-Erkennung und Plain-Text-Fallback für saubere Ausgaben in GitHub Actions und GitLab CI
10. Zusammenfassung
Professionelle CLI-UX in Bash ist kein Luxus, sondern eine operative Notwendigkeit für Skripte, die im Produktionsbetrieb eingesetzt werden. Die beschriebenen Techniken — tput für portable Terminalsteuerung, ANSI-Codes für präzise Formatierung, Spinner und Fortschrittsbalken für lang laufende Operationen, column und printf für strukturierte Tabellen und read/select für interaktive Prompts — lassen sich in eine gemeinsame Library auslagern und über alle Skripte konsistent einsetzen.
Die wichtigste Grundregel bleibt: Jede UX-Komponente muss mit TTY-Erkennung kombiniert werden, sodass Skripte in CI-Pipelines, Cron-Jobs und Pipe-Kontexten automatisch auf Plain-Text-Ausgabe umschalten. Ein Spinner oder ein farbiger Fortschrittsbalken, der in einer CI-Logdatei als unlesbares Steuerzeichen-Kauderwelsch erscheint, ist schlechter als keine Formatierung. Mit dem hier beschriebenen Ansatz — zentralisierte Library, defensive Terminal-Prüfung und klare Trennung von stdout und stderr — entsteht CLI-UX in Bash, die in allen Umgebungen funktioniert.
CLI-UX in Bash — Das Wichtigste auf einen Blick
Farben & tput
tput für portable Terminal-Attribute verwenden. Farbvariablen bei Initialisierung setzen und auf leere Strings fallen lassen, wenn kein Terminal erkannt wird.
Spinner & Progress
Hintergrundprozess mit \r-Überschreiben. Cursor verstecken während aktiv, trap auf EXIT für sauberes Cleanup.
Tabellen
column -t für dynamische Breiten, printf mit Formatspezifikationen für feste Reports. Farbige Header mit BOLD/RESET.
TTY-Erkennung
[[ -t 2 ]] vor jeder UX-Initialisierung. Automatischer Plain-Text-Fallback für CI, Cron und Pipe-Kontexte.