SSD Nodes Learn 🎉 VPS ab $4.99/Monat
Anleitungen Matt ConnorVon Matt Connor · Aktualisiert 2026-08-07

Claude Code Statuszeile auf einem VPS einrichten

Richten Sie statusLine in settings.json ein und zeigen Sie Hostname, Verzeichnis, Git-Branch und Modell unter dem Prompt an, damit Sie den richtigen Server bearbeiten.

Was eine Claude Code-Statuszeile anzeigt

Eine Claude Code-Statuszeile ist eine Zeile unter dem Prompt. Sie zeigt die Ausgabe eines von Ihnen erstellten Skripts an. Sie fügen einen Block `statusLine zu settings.json` hinzu und verweisen darin auf einen Befehl. Claude Code führt diesen Befehl aus, übergibt ihm den Sitzungsstatus als JSON über die Standardeingabe und gibt alles aus, was der Befehl auf die Standardausgabe schreibt.

Das ist die vollständige Schnittstelle. Ihr Skript liest JSON über stdin und gibt Text über stdout aus. Es läuft auf Ihrem Rechner. Nichts von seiner Ausgabe wird an das Modell gesendet. Dadurch entstehen keine Token-Kosten.

Auf einem Laptop mit einem Projekt ist das nur eine Anzeige. Auf drei Servern ist sie eine Sicherheitsmaßnahme. Jede Claude Code-Sitzung sieht in jedem Terminal gleich aus. Vier nicht beschriftete SSH-Fenster führen daher leicht dazu, dass eine Migration auf dem falschen Server ausgeführt wird. Eine Statuszeile, die mit dem Hostnamen beginnt, verhindert diese Fehlerklasse.

Wo sich die Einstellung statusLine in settings.json befindet

Legen Sie sie in Ihren Benutzereinstellungen unter ~/.claude/settings.json ab. Diese Einstellung gilt für jedes Projekt auf dem betreffenden Rechner. Projekteinstellungen unter .claude/settings.json innerhalb eines Repositorys funktionieren ebenfalls und haben für dieses Verzeichnis Vorrang.

{
  "statusLine": {
    "type": "command",
    "command": "~/.claude/statusline.sh"
  }
}

type lautet immer "command". Der Wert command wird über eine Shell ausgeführt. Er kann daher ein Skriptpfad oder ein einfacher Befehl sein. Prüfen Sie zunächst die Verbindung, bevor Sie ein Skript schreiben:

{
  "statusLine": {
    "type": "command",
    "command": "hostname -s"
  }
}

Starten Sie Claude Code und senden Sie eine Nachricht. Die Leiste unter der Eingabeaufforderung zeigt nun den kurzen Hostnamen des Servers an. Bleibt sie leer, liegt das Problem an der Einstellung oder am Vertrauensdialog, nicht an Ihrem Skript. Lesen Sie weiter unten den Abschnitt „Warum die Statuszeile leer bleibt“.

Seit August 2026 gibt es drei optionale Schlüssel. padding fügt horizontalen Abstand in Zeichen hinzu und hat standardmäßig den Wert 0. refreshInterval führt den Befehl zusätzlich zu den normalen Auslösern alle N Sekunden erneut aus, mindestens jedoch alle 1 Sekunden. Das benötigen Sie nur, wenn die Zeile eine Uhr oder einen anderen Wert anzeigt, der sich ändert, während die Sitzung inaktiv bleibt. hideVimModeIndicator unterdrückt den integrierten Text -- INSERT --, wenn Ihr eigenes Skript den Vim-Modus bereits darstellt.

Welche Daten empfängt das Statuszeilenskript?

Vertrauen Sie keiner Feldliste, die Sie irgendwo lesen, auch nicht dieser Seite. Erfassen Sie das tatsächliche Objekt, das Ihre Version sendet. Schreiben Sie ein temporäres Skript, das stdin in eine Datei schreibt:

cat > ~/.claude/statusline-capture.sh <<'EOF'
#!/bin/bash
cat > /tmp/statusline-input.json
echo "captured"
EOF
chmod +x ~/.claude/statusline-capture.sh

Verweisen Sie statusLine.command auf diese Datei, starten Sie eine Sitzung und senden Sie eine Nachricht. Die Statusleiste liest captured. Sehen Sie sich nun an, was angekommen ist:

jq . /tmp/statusline-input.json

Damit kennen Sie die genaue Struktur Ihres Builds. Sie können diesen Vorgang jederzeit wiederholen, wenn ein Update etwas ändert.

Die stabilen Teile bestehen laut Dokumentation von August 2026 aus verschachtelten Objekten und nicht aus flachen Schlüsseln. model enthält id und display_name. workspace enthält current_dir und project_dir: current_dir bezeichnet das aktuelle Sitzungsverzeichnis, project_dir das Verzeichnis, in dem die Sitzung gestartet wurde. Die beiden Werte unterscheiden sich, sobald sich das Arbeitsverzeichnis während der Sitzung ändert. Das Feld cwd auf oberster Ebene enthält denselben Wert wie workspace.current_dir. context_window enthält die Token-Anzahlen sowie einen vorab berechneten Wert für used_percentage. cost enthält total_cost_usd und die Zeitdauerzähler. session_id bleibt während der gesamten Sitzung unverändert und ist sitzungsübergreifend eindeutig. Das ist später für das Caching wichtig.

Drei Regeln halten ein Skript auch bei Änderungen am Schema funktionsfähig.

Einige Schlüssel fehlen und sind nicht null. vim, agent, pr, worktree und effort erscheinen nur, wenn die zugehörige Funktion aktiv ist. Wenn Sie .vim.mode mit jq -r auslesen, während der vim-Modus deaktiviert ist, gibt der Befehl die Zeichenfolge null aus. Ihre Statusleiste zeigt dem Leser dann null an. Fügen Sie // empty an jeden Selektor an. Dann gibt ein fehlender Schlüssel überhaupt nichts aus.

Einige Werte sind anfangs null. context_window.used_percentage und context_window.current_usage sind vor der ersten API-Antwort null. current_usage wird nach /compact wieder null, bis der nächste Aufruf den Wert erneut setzt. Eine Kontextprozentanzeige in der Statusleiste benötigt daher // 0. Andernfalls liest sie in den ersten Sekunden jeder Sitzung null. Bevor Sie diese Zahl in einer Statusleiste anzeigen, sollten Sie wissen, wie das Kontextfenster tatsächlich gefüllt wird.

Der Git-Branch steht nicht im JSON. Es gibt kein Feld, das ihn ausgibt. Ein Branch in Ihrer Statusleiste stammt daher ausschließlich daraus, dass Ihr Skript selbst git ausführt.

Eine Statuszeile, die bei Fehlern mit Fallbacks weiterarbeitet

Dies ist die Version zum Kopieren und Einfügen. Sie gibt den Hostnamen, das Arbeitsverzeichnis, den Git-Branch und den Modellnamen aus. Für jedes Feld gibt es einen Fallback. Dadurch erzeugt selbst ein leeres JSON-Objekt eine nutzbare Zeile.

#!/bin/bash
# ~/.claude/statusline.sh
input=$(cat)

# Read one field. Prints nothing when the key is missing or null.
field() { printf '%s' "$input" | jq -r "$1 // empty" 2>/dev/null; }

HOST=$(hostname -s 2>/dev/null)
[ -z "$HOST" ] && HOST="host"

DIR=$(field '.workspace.current_dir')
[ -z "$DIR" ] && DIR=$(field '.cwd')
[ -z "$DIR" ] && DIR="$PWD"

MODEL=$(field '.model.display_name')
[ -z "$MODEL" ] && MODEL="claude"

SHORT="$DIR"
if [ -n "$HOME" ]; then
  case "$DIR" in
    "$HOME") SHORT="~" ;;
    "$HOME"/*) SHORT="~/${DIR#"$HOME"/}" ;;
  esac
fi

BRANCH=""
if git -C "$DIR" rev-parse --git-dir >/dev/null 2>&1; then
  BRANCH=$(git -C "$DIR" branch --show-current 2>/dev/null)
  [ -z "$BRANCH" ] && BRANCH="detached"
fi

CYAN=$'\033[36m'
YELLOW=$'\033[33m'
DIM=$'\033[2m'
RESET=$'\033[0m'

LINE="${CYAN}${HOST}${RESET} ${SHORT}"
[ -n "$BRANCH" ] && LINE="${LINE} ${YELLOW}${BRANCH}${RESET}"
LINE="${LINE} ${DIM}${MODEL}${RESET}"

printf '%s\n' "$LINE"

Jeder Lesezugriff läuft über field. Dabei wird // empty angehängt. Ein umbenannter oder entfernter Schlüssel erzeugt dadurch eine leere Zeichenfolge. In der nächsten Zeile wird dann ein Standardwert verwendet. Das Verzeichnis fällt von workspace.current_dir auf cwd und anschließend auf $PWD zurück. Der Branch wird über git -C "$DIR" und nicht über ein einfaches git ermittelt. Dadurch entspricht der Branch immer dem Verzeichnis, das die Leiste anzeigt.

Speichern Sie die Datei und machen Sie sie anschließend ausführbar:

chmod +x ~/.claude/statusline.sh

Das Ausführungsbit ist erforderlich. Claude Code führt den Befehl über eine Shell aus. Ein Skript ohne +x schlägt daher mit Permission denied fehl, gibt nichts auf stdout aus und die Zeile bleibt ohne sichtbaren Fehler leer.

jq verarbeitet JSON auf der Kommandozeile und ist auf einem frisch installierten Ubuntu-Server nicht vorhanden:

sudo apt update && sudo apt install -y jq

Verweisen Sie die Einstellung anschließend auf das Skript. Verwenden Sie dabei den ersten settings.json-Block von oben.

Skripten testen, bevor Sie ihnen vertrauen

Führen Sie das Skript zweimal manuell aus. Zuerst mit einem normalen Sitzungsobjekt:

echo '{"model":{"display_name":"Opus"},"workspace":{"current_dir":"/srv/api"},"session_id":"t1"}' | ~/.claude/statusline.sh

Sie erhalten den Hostnamen, dann /srv/api und anschließend Opus. Es wird kein Branch angezeigt, weil /srv/api auf Ihrem Rechner wahrscheinlich kein Git-Repository ist.

Führen Sie anschließend den Degradationstest durch. Diesen überspringen viele:

echo '{}' | ~/.claude/statusline.sh

Ein leeres Objekt ist der schlimmste Fall, den eine Schemaänderung liefern kann. Die Zeile gibt weiterhin den Hostnamen, das aktuelle Verzeichnis aus $PWD und an der Stelle des Modellnamens das Wort claude aus. Es tritt kein Fehler auf, und null wird nicht ausgegeben. Ein Skript, das diesen Test besteht, übersteht die Umbenennung eines Feldes, weil ein umbenanntes und ein fehlendes Feld für Ihr Skript dasselbe Ereignis sind.

Was Sie sehen sollten

Die Statuszeile wird in einer eigenen Zeile oberhalb der integrierten Fußzeilen-Badges angezeigt und ersetzt diese nicht. Bei einer funktionierenden Konfiguration enthält sie eine Zeile: den kurzen Hostnamen in Cyan, anschließend das Arbeitsverzeichnis, wobei Ihr Home-Verzeichnis zu ~ verkürzt wird, dann den Branchnamen in Gelb, wenn das Verzeichnis ein Git-Repository ist, und schließlich den abgedunkelten Modellnamen. Das Ergebnis sollte ungefähr web-01 ~/api main Opus entsprechen, wobei diese vier Bestandteile farbig dargestellt werden.

Die Zeile führt Ihr Skript erneut aus, wenn eine Sitzung gestartet oder einschließlich eines Resume fortgesetzt wird, wenn eine neue Assistant-Nachricht eintrifft, nachdem /compact abgeschlossen ist, wenn sich der Berechtigungsmodus ändert, wenn der Vim-Modus umgeschaltet wird und bei einem refreshInterval-Intervall, falls Sie eines festlegen. Aktualisierungen werden 300 ms lang zusammengefasst, sodass das Skript bei einer Folge von Änderungen nur einmal ausgeführt wird. Während der Autovervollständigung, des Hilfemenüs und der Berechtigungsabfragen wird die Leiste ausgeblendet und anschließend wieder angezeigt.

Warum der Hostname an erster Stelle steht

Wenn Sie Agents auf mehr als einem Server ausführen, teilt Ihnen im Terminal nur die Anzeige mit, wo Sie sich befinden. Und Terminals können irreführen. Öffnen Sie aus einem tmux-Fenster eine zweite ssh-Verbindung, bleibt im Fenstertitel häufig der alte Name stehen, weil die Shell den Wechsel nicht erkannt hat. Lassen Sie Claude Code in einer getrennten tmux-Sitzung auf einem VPS laufen und verbinden Sie sich einen Tag später erneut, unterscheidet auf dem Bildschirm nichts zwischen dem Build-Server und dem Produktionssystem.

Die Statuszeile ist anders, weil Claude Code sie für jede Sitzung selbst aus den Sitzungsdaten rendert. Sie kann nicht aus dem falschen Fenster übernommen werden und bleibt nicht wegen einer Shell-Eingabeaufforderung veraltet, die nicht aktualisiert wurde. Sie zeigt an, auf welchem System der Agent Dateien schreibt.

Geben Sie jedem Server eine eigene Farbe. So erkennen Sie ihn, bevor Sie den Namen lesen. Fügen Sie diese beiden Zeilen oberhalb der LINE=-Zuweisung ein:

CODE=$(printf '%s' "$HOST" | cksum | cut -d' ' -f1)
HOST_COLOR=$(printf '\033[%dm' "$((31 + CODE % 6))")

Verwenden Sie anschließend ${HOST_COLOR} anstelle von ${CYAN}. cksum gibt eine Prüfsumme des Hostnamens aus. Dadurch wird jeder Name immer derselben Farbe im Bereich von 31 bis 36 zugeordnet, also Rot bis Cyan. Kopieren Sie dasselbe Skript auf jedes System. Dann kennzeichnet sich jedes System selbst.

Das Verzeichnis ist aus demselben Grund sinnvoll. /srv/api und /srv/api-staging liegen in einem ssh-Befehl nur einen Tastendruck auseinander, haben aber im Fehlerfall völlig unterschiedliche Auswirkungen. Modell und Branch sind die beiden anderen Informationen, die den Platz wert sind. Das Modell zeigt, welche Sitzung Sie fortgesetzt haben. Der Branch zeigt, ob der Agent gleich auf main committen wird.

Auf einem kleinen Bildschirm ist das besonders wichtig, weil kein Fenstertitel als zusätzliche Orientierung verfügbar ist. Wenn das auf Ihre Umgebung zutrifft, lesen Sie Claude Code von einem Telefon aus steuern.

Das Skript schnell halten

Ihr Skript wird bei jeder Nachricht des Assistenten ausgeführt. Claude Code bricht einen laufenden Aufruf ab, sobald ein neues Update eintrifft. Ein langsames Skript zeigt daher veralteten Text oder überhaupt keinen Text an.

Jeder Aufruf von jq kostet wenige Millisekunden. git ist der langsame Teil: git status in einem großen Repository mit leerem Cache benötigt Hunderte von Millisekunden. Das obige Skript verwendet git status absichtlich nicht. Stattdessen ruft es git branch --show-current auf. Dieser Befehl liest .git/HEAD und wird sofort beendet.

Wenn Sie etwas aufwendigeres hinzufügen, speichern Sie das Ergebnis in einer Datei zwischen und aktualisieren Sie es alle paar Sekunden. Verwenden Sie die Sitzung als Bestandteil des Dateinamens:

CACHE="/tmp/statusline-$(field '.session_id')"

Verwenden Sie session_id, nicht $$. $$ ist die Prozess-ID Ihres Skripts. Sie ist bei jedem einzelnen Aufruf anders. Ein darauf basierender Cache wird daher nie verwendet, und bei jedem Aufruf entstehen die vollständigen Kosten. session_id bleibt während der gesamten Sitzung stabil und unterscheidet sich zwischen Sitzungen. Dadurch können zwei Claude-Code-Sitzungen in zwei Repositories nicht den zwischengespeicherten Branchnamen der jeweils anderen Sitzung lesen.

Eine weitere Einschränkung ist wichtig: tput cols funktioniert nicht innerhalb eines Statusline-Skripts. Claude Code erfasst die Ausgabe, statt Ihr Skript an das Terminal anzuhängen. Daher gibt es keine Terminalbreite, die ermittelt werden könnte. Claude Code setzt die Umgebungsvariablen COLUMNS und LINES vor der Ausführung des Befehls. Dies gilt ab v2.1.153. Lesen Sie daher $COLUMNS aus, wenn Sie festlegen müssen, wie viel Text ausgegeben werden soll.

Warum die Statuszeile leer bleibt

Es wird überhaupt nichts angezeigt. Prüfen Sie das Ausführungsbit mit ls -l ~/.claude/statusline.sh und führen Sie das Skript anschließend mit der obigen Testeingabe manuell aus. Wenn es in der Shell eine Zeile ausgibt, aber nicht in Claude Code, beginnen Sie mit claude --debug. Dieser Befehl protokolliert den Exit-Code und die Standardfehlerausgabe des ersten Statuszeilenaufrufs der Sitzung.

Im Debug-Log steht Status line command skipped: workspace trust not accepted. Die Statuszeile führt einen Shell-Befehl aus und unterliegt daher derselben Workspace-Vertrauensprüfung wie Hooks. Solange Sie den Vertrauensdialog für dieses Verzeichnis nicht bestätigen, wird der Befehl nicht ausgeführt. Das kommt auf einem VPS häufig vor, weil jeder neue Clone in einem Verzeichnis liegt, das Claude Code noch nicht kennt. Starten Sie Claude Code in diesem Verzeichnis neu und bestätigen Sie den Dialog.

Alles bleibt leer und disableAllHooks ist gesetzt. "disableAllHooks": true in settings.json deaktiviert ebenfalls die Statuszeile, weil es dieselbe Ausführungssperre für Shell-Befehle ist. Entfernen Sie die Einstellung oder setzen Sie sie auf false.

Die Zeile gibt null aus. Ein jq-Selektor hat einen Schlüssel erreicht, der fehlt oder null ist, und jq -r gibt null als die vier Zeichen null aus. Ergänzen Sie // empty für Text und // 0 für Zahlen.

Die Zeile bleibt direkt nach dem Bearbeiten des Skripts leer. Ein Befehl, der mit einem Fehlercode beendet wird oder nichts ausgibt, leert die Zeile. Die häufigste Ursache ist eine letzte Zeile wie [ -n "$BRANCH" ] && LINE="...". Sie beendet das Skript mit 1, wenn der Zweig leer ist, und übernimmt diesen Exit-Code für das gesamte Skript. Lassen Sie printf am Ende stehen oder ergänzen Sie exit 0.

Escape-Codes werden als Text angezeigt, beispielsweise \e]8;; in der Leiste. Verwenden Sie printf '%b' anstelle von echo -e. Klickbare OSC-8-Links benötigen außerdem ein Terminal, das diese unterstützt. tmux oder SSH können die Sequenzen entfernen. Auf einem Remote-System ist eine einfache Farbausgabe daher die sicherere Wahl.

Die rechte Seite der Zeile wird abgeschnitten. Systembenachrichtigungen und der Tokenzähler für den ausführlichen Modus verwenden diese Zeile ebenfalls von rechts. Bei einem schmalen Terminal kommt es zu Überlappungen. Halten Sie die Ausgabe kurz. Eine genaue Abrechnung der Nutzung statt einer Zahl in der Leiste finden Sie unter wie Claude Code Token zählt.

FAQ

Wo ist die Einstellung für die Claude Code-Statuszeile gespeichert?

In settings.json als Block statusLine, wobei type auf "command" und command auf einen Skriptpfad oder einen Shell-Befehl gesetzt ist. Die Benutzereinstellungen befinden sich in ~/.claude/settings.json und gelten für jedes Projekt auf diesem Rechner. Die Projekteinstellungen befinden sich in .claude/settings.json innerhalb des Repositorys und haben für dieses Verzeichnis Vorrang. Die Einstellungen werden automatisch neu geladen. Eine Änderung wird jedoch erst beim nächsten Aktualisierungsereignis sichtbar, beispielsweise bei Ihrer nächsten Nachricht.

Warum bleibt meine Claude Code-Statuszeile leer?

Nahezu alle Fälle lassen sich auf vier Ursachen zurückführen. Dem Skript fehlt das Ausführungsbit. Deshalb gibt die Shell Permission denied zurück, und es gelangt nichts nach stdout. Der Dialog zur Vertrauensstellung des Arbeitsbereichs wurde nicht bestätigt, und claude --debug protokolliert Status line command skipped: workspace trust not accepted. disableAllHooks ist true, wodurch die Statuszeile unter derselben Bedingung deaktiviert wird. Oder das Skript wird mit einem Exit-Code ungleich null beendet, wodurch die Zeile leer bleibt. Testen Sie das Skript zunächst manuell: echo '{}' | ~/.claude/statusline.sh muss eine Ausgabe erzeugen.

Enthält das JSON der Statuszeile den Git-Branch?

Nein. Das JSON enthält Sitzungsdaten wie das Modell, die Arbeitsbereichsverzeichnisse, die Werte des Kontextfensters und die Kosten. Es enthält keine Git-Informationen. Ein Branch in Ihrer Statusleiste stammt aus Ihrem eigenen Skript, das git branch --show-current aufruft. Übergeben Sie das Verzeichnis aus dem JSON mit git -C "$DIR", damit der Branch immer dem Verzeichnis entspricht, das die Statusleiste anzeigt.

Verbraucht die Statuszeile Tokens oder verlangsamt sie die Sitzung?

Sie verbraucht keine Tokens, weil das Skript lokal ausgeführt wird und seine Ausgabe nie an das Modell gesendet wird. Für die Geschwindigkeit sind Sie verantwortlich. Der Befehl wird bei jeder Assistentennachricht mit einer Verzögerung von 300 ms ausgeführt. Claude Code bricht eine laufende Ausführung ab, sobald eine neue Aktualisierung eintrifft. Dauert ein Skript eine volle Sekunde, zeigt es daher veralteten Text an. Vermeiden Sie git status in großen Repositorys und speichern Sie langsame Ergebnisse in einer Datei zwischen, deren Schlüssel auf session_id basiert.

Wie zeige ich auf jedem Server eine andere Statuszeile an?

Verwenden Sie ein Skript und lassen Sie es den Rechner auslesen. Das obige Skript gibt $HOSTNAME aus und verwendet hostname -s als Fallback. Dadurch beschriftet dieselbe Datei, die auf jeden Rechner kopiert wird, jeden Rechner korrekt. Der Farbmechanismus auf Basis der Prüfsumme weist jedem Hostnamen außerdem eine eigene Farbe zu. Wenn ein Server ein anderes Layout benötigt, fügen Sie im Repository, in dem Sie auf diesem Rechner arbeiten, einen Block statusLine in den Projekteinstellungen ein. Die Projekteinstellungen haben für dieses Verzeichnis Vorrang vor den Benutzereinstellungen.