VPS 設定 Claude Code 狀態列
透過 statusLine 執行指令碼,將主機名稱、目錄、Git 分支與模型顯示在提示字元下方,避免在錯誤的 VPS 上操作。
Claude Code 狀態列顯示的內容
Claude Code 狀態列位於提示字元下方,會顯示您撰寫的指令碼輸出內容。您可以在 settings.json 中加入 statusLine 區塊,並指定要執行的命令。Claude Code 會執行該命令,將工作階段狀態以 JSON 格式透過標準輸入傳給命令,然後顯示命令寫入標準輸出的內容。
這就是完整的介面規範。您的指令碼會從標準輸入讀取 JSON,並將文字寫入標準輸出。指令碼會在您的電腦上執行,輸出的任何內容都不會傳送給模型,因此不會消耗 token。
在只有一個專案的筆記型電腦上,這只是裝飾。在 3 台伺服器上,這是安全防護。每個 Claude Code 工作階段在每個終端機中看起來都一樣,因此 4 個沒有標籤的 SSH 視窗可能讓遷移作業誤執行在錯誤的伺服器上。以主機名稱開頭的狀態列,可以避免這類錯誤。
statusLine 設定在 settings.json 中的位置
將設定放在 ~/.claude/settings.json 的使用者設定中。這會套用到該電腦上的所有專案。也可以在儲存庫內的 .claude/settings.json 設定專案層級的值,且該目錄會優先使用這個值。
{
"statusLine": {
"type": "command",
"command": "~/.claude/statusline.sh"
}
}type 一律為 "command"。command 值會透過 shell 執行,因此可以是指令碼路徑或一般命令。先確認設定連線正常,再撰寫任何指令碼:
{
"statusLine": {
"type": "command",
"command": "hostname -s"
}
}啟動 Claude Code 並傳送一則訊息。提示字元下方的列現在會顯示伺服器的短主機名稱。如果仍然空白,問題出在設定或信任對話方塊,而不是你的指令碼。請參閱下方的「為什麼 statusline 保持空白」。
截至 August 2026,共有 3 個選用索引鍵。padding 會增加以字元計算的水平間距,預設值為 0。refreshInterval 會在一般觸發條件之外,每 N 秒重新執行命令一次,最短間隔為 1。只有在列中顯示時鐘,或顯示工作階段閒置時仍會變動的內容時,才需要使用這項設定。當你自己的指令碼已經呈現 vim 模式時,hideVimModeIndicator 會隱藏內建的 -- INSERT -- 文字。
狀態列指令碼會收到哪些資料?
不要相信任何地方讀到的欄位清單,包括本頁。請擷取你的版本實際傳送的物件。撰寫一個用完即丟的指令碼,將 stdin 儲存至檔案:
cat > ~/.claude/statusline-capture.sh <<'EOF'
#!/bin/bash
cat > /tmp/statusline-input.json
echo "captured"
EOF
chmod +x ~/.claude/statusline-capture.sh讓 statusLine.command 指向該檔案,啟動工作階段,並傳送一則訊息。狀態列會讀取 captured。現在查看實際收到的內容:
jq . /tmp/statusline-input.json這就是你的建置版本使用的確切結構。日後更新導致結構變更時,也可以隨時重複這項操作。
截至 2026 年 8 月,文件記載的穩定部分是巢狀物件,而不是扁平鍵值。model 包含 id 和 display_name。workspace 包含 current_dir 和 project_dir:current_dir 是目前的工作目錄,project_dir 是啟動工作階段時的工作目錄;工作階段中途變更工作目錄後,兩者便會不同。頂層的 cwd 會帶有與 workspace.current_dir 相同的值。context_window 包含 token 計數,以及預先計算的 used_percentage。cost 包含 total_cost_usd 和持續時間計數器。session_id 在整個工作階段期間保持穩定,且在不同工作階段之間具有唯一性,這對之後實作快取很重要。
以下 3 項規則可讓指令碼在結構變更後仍能運作。
部分鍵值會缺少,而不是設定為 null。 vim、agent、pr、worktree 和 effort 只會在對應功能啟用時出現。vim 模式關閉時,使用 jq -r 讀取 .vim.mode 會輸出字面值 null,狀態列則會向讀者顯示 null。請在每個 selector 後附加 // empty,如此一來,缺少的鍵值就完全不會輸出任何內容。
部分值在早期會是 null。 context_window.used_percentage 和 context_window.current_usage 在第一次 API 回應前為 null,而 current_usage 在 /compact 之後會恢復為 null,直到下一次呼叫重新填入值。因此,狀態列上的 context 百分比需要使用 // 0;否則每個工作階段開始後的前幾秒都會讀取 null。將這個數字放到狀態列前,先了解 context window 實際如何填滿,會有所幫助。
git 分支不在 JSON 中。 JSON 沒有任何欄位會回報分支。狀態列上的分支名稱,是由你的指令碼自行執行 git 取得的。
狀態列腳本:發生問題時降級,而不是失效
這是可直接複製貼上的版本。它會顯示主機名稱、工作目錄、Git 分支和模型名稱。每個欄位都有備援值,因此即使 JSON 物件為空,仍會產生可用的狀態列。
#!/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"每次讀取都會透過 field,並附加 // empty。因此,重新命名或移除的索引鍵會產生空字串,下一行則會提供預設值。目錄會依序從 workspace.current_dir、cwd 降級到 $PWD。分支會來自 git -C "$DIR",而不是單獨使用 git,因此分支一定會與狀態列顯示的目錄一致。
儲存後,將它設為可執行:
chmod +x ~/.claude/statusline.sh執行權限不是可選項目。Claude Code 會透過 shell 執行此命令,因此缺少 +x 的腳本會因 Permission denied 而失敗,不會產生 stdout,且該列會保持空白,不顯示任何錯誤。
jq 會在命令列解析 JSON,而全新的 Ubuntu server 預設未安裝此工具:
sudo apt update && sudo apt install -y jq接著將設定指向此腳本,使用上方第一個 settings.json 區塊。
在信任指令碼前先進行測試
手動執行兩次。第一次使用正常的工作階段物件:
echo '{"model":{"display_name":"Opus"},"workspace":{"current_dir":"/srv/api"},"session_id":"t1"}' | ~/.claude/statusline.sh您會依序取得主機名稱、/srv/api,以及 Opus。不會出現分支名稱,因為您電腦上的 /srv/api 可能不是 git repository。
第二次進行降級測試。這是最容易被略過的測試:
echo '{}' | ~/.claude/statusline.sh空物件是結構描述變更可能交給您的最差情況。該行仍會列印主機名稱、$PWD 所提供的目前目錄,以及模型名稱位置的 claude。不會發生錯誤,也不會列印 null。通過這項測試的指令碼,即使欄位重新命名也能正常運作,因為對指令碼而言,欄位重新命名與欄位遺失是相同的事件。
應顯示的內容
狀態列會在內建頁尾徽章上方獨立顯示一列,不會取代這些徽章。設定正常時,該列包含 4 個部分:以青色顯示的短主機名稱、將家目錄折疊為 ~ 的工作目錄、工作目錄是 git repository 時以黃色顯示的分支名稱,以及以暗色顯示的模型名稱。整體應接近 web-01 ~/api main Opus,並為這 4 個部分套用對應色彩。
工作階段啟動時(包括 resume)、收到新的 assistant 訊息時、/compact 完成後、權限模式變更時、vim 模式切換時,以及設定 refreshInterval tick 時,這一列會重新執行指令碼。更新會延遲 300 ms 進行去抖動,因此一連串變更只會執行指令碼一次。自動完成、說明功能表和權限提示顯示期間,狀態列會隱藏,之後恢復顯示。
主機名稱應該放在最前面
當你在多台伺服器上執行 agent 時,終端機是唯一告訴你目前位置的資訊,但終端機可能會誤導你。在 tmux pane 內建立第二個 ssh 連線時,視窗標題通常仍保留舊名稱,因為設定標題的 shell 不知道連線已經切換。讓 Claude Code 在 VPS 的分離 tmux 工作階段中執行,隔天重新連接後,畫面上沒有任何資訊能區分建置伺服器與正式環境主機。
statusline 不同,因為它由 Claude Code 本身依每個工作階段呈現,使用該工作階段持有的資料。它不會從錯誤的 pane 繼承內容,也不會因未重新整理的 shell 提示字元而停留在過時狀態。它顯示的是 agent 寫入檔案所在的主機。
為每台伺服器指定不同顏色,讓你在閱讀前就能辨識主機。在 LINE= 指派上方加入以下兩行:
CODE=$(printf '%s' "$HOST" | cksum | cut -d' ' -f1)
HOST_COLOR=$(printf '\033[%dm' "$((31 + CODE % 6))")接著以 ${HOST_COLOR} 取代 ${CYAN}。cksum 會輸出主機名稱的 checksum,因此相同名稱總會對應到 31 到 36 的相同顏色,也就是從紅色到青色。將相同的 script 複製到每台主機,每台主機就會自行標示。
目錄也基於相同原因值得顯示。在 ssh 指令中,/srv/api 與 /srv/api-staging 只差一個按鍵,但實際影響可能相差整起事件。模型與 branch 是另外兩項值得佔用欄位的資訊:模型能告訴你恢復的是哪個工作階段,而 branch 能告訴你 agent 是否即將提交到 main。
在小螢幕上,這些資訊更重要,因為沒有視窗標題可供依靠。如果你的環境就是如此,請參閱 使用手機操作 Claude Code。
讓指令碼保持快速
您的指令碼會在每則 assistant 訊息時執行,而 Claude Code 會在收到新的更新時取消進行中的執行。因此,指令碼執行緩慢時,畫面可能顯示過時文字,或完全沒有文字。
每次 jq 呼叫只需幾毫秒。速度變慢的部分是 git:在大型 repository 中,冷快取狀態下執行 git status 需要數百毫秒。上述指令碼刻意避免 git status,改為呼叫 git branch --show-current;它會讀取 .git/HEAD,並立即返回。
如果要加入較耗時的處理,請將結果快取在檔案中,並每隔幾秒重新整理。請以工作階段作為檔案的索引:
CACHE="/tmp/statusline-$(field '.session_id')"請使用 session_id,不要使用 $$。$$ 是指令碼的 process ID,每次執行都不同,因此以它作為索引的快取永遠無法命中,每次都必須付出完整成本。session_id 在整個工作階段期間保持穩定,且不同工作階段之間不會重複,因此兩個位於不同 repository 的 Claude Code 工作階段無法讀取彼此快取的分支名稱。工作階段依設計彼此隔離;若要讓其中一個工作階段將工作交給另一個工作階段,必須明確執行此步驟。因此,從一個 Claude Code 工作階段傳送訊息到另一個工作階段便是為此用途。
還有一項值得注意的限制:tput cols 無法在 statusline 指令碼內運作。Claude Code 會擷取輸出,而不是將您的指令碼連接至終端機,因此沒有可供寬度偵測使用的測量對象。在 v2.1.153 及更新版本中,Claude Code 會在執行命令前設定 COLUMNS 和 LINES 環境變數;需要決定輸出多少內容時,請讀取 $COLUMNS。
狀態列為何維持空白
完全沒有任何顯示。 使用 ls -l ~/.claude/statusline.sh 檢查執行位元,然後以手動方式搭配上述模擬輸入執行指令碼。如果指令碼在 shell 中會輸出一行文字,但在 Claude Code 中沒有輸出,請先使用 claude --debug。此選項會記錄工作階段第一次執行狀態列時的結束代碼與 stderr。
偵錯日誌顯示 Status line command skipped: workspace trust not accepted。 狀態列會執行 shell 命令,因此受 hooks 使用的相同工作區信任閘門控制。在接受該目錄的信任對話框前,命令不會執行。這在 VPS 上很常見,因為每個新複製的儲存庫都是 Claude Code 尚未見過的目錄。請在該目錄中重新啟動 Claude Code,並接受對話框。
所有內容都是空白,且已設定 disableAllHooks。 settings.json 中的 "disableAllHooks": true 也會停用狀態列,因為它使用相同的 shell 執行閘門。請移除它,或將其設為 false。
列印出的內容為 null。 jq 選取器存取了不存在或值為 null 的鍵,而 jq -r 會將 null 輸出為 4 個字元的 null。文字請加入 // empty,數字請加入 // 0。
編輯指令碼後,列出的內容立即變成空白。 結束代碼非 0 或沒有輸出的命令,都會使該列變成空白。常見原因是最後一行使用類似 [ -n "$BRANCH" ] && LINE="..." 的內容;當分支為空時,它會以 1 結束,並使整個指令碼採用該結束代碼。請讓 printf 保持在最後,或加入 exit 0。
跳脫碼以純文字顯示,例如列中出現 \e]8;;。請使用 printf '%b',不要使用 echo -e。可點選的 OSC 8 連結也需要終端機支援;tmux 或 SSH 可能會移除這些序列,因此在遠端主機上使用一般色彩較為可靠。
列的右側遭到截斷。 系統通知與 verbose 模式的 token 計數器會從右側共用該列,而狹窄的終端機會讓兩者重疊。請縮短輸出。如需精確計算使用量,而不是查看列上的數字,請參閱 Claude Code 如何計算 token。
FAQ
Claude Code 的狀態列設定位於何處?
設定位於 settings.json 中,使用 statusLine 區塊,並將 type 設為 "command",將 command 設為指令碼路徑或 shell 命令。使用者設定位於 ~/.claude/settings.json,會套用到該電腦上的所有專案。專案設定位於儲存庫中的 .claude/settings.json,並優先套用於該目錄。設定會自動重新載入,但變更要到下一次更新觸發時才會顯示,例如下一則訊息送出後。
為什麼我的 Claude Code 狀態列是空白的?
幾乎所有情況都可歸納為 4 個原因。指令碼沒有執行權限,因此 shell 會回傳 Permission denied,而 stdout 沒有任何輸出。工作區信任對話框尚未接受,且 claude --debug 會記錄 Status line command skipped: workspace trust not accepted。disableAllHooks 為 true,會在相同的控管條件下停用狀態列。或者指令碼以非零狀態結束,導致該列變成空白。請先手動測試:echo '{}' | ~/.claude/statusline.sh 必須輸出內容。
狀態列 JSON 是否包含 git 分支?
不包含。JSON 會提供工作階段狀態,例如模型、工作區目錄、上下文視窗數值與成本。其中沒有任何 git 資訊。狀態列上的分支名稱來自你自己的指令碼呼叫 git branch --show-current。請使用 git -C "$DIR" 從 JSON 傳入目錄,讓分支永遠與狀態列顯示的目錄一致。
狀態列會消耗 token 或拖慢工作階段嗎?
不會消耗 token,因為指令碼在本機執行,其輸出也不會傳送給模型。速度由你負責。該命令會在每則 assistant 訊息上執行,並使用 300 ms 的 debounce。Claude Code 會在新的更新抵達時取消正在執行的程序,因此指令碼若完整執行需要 1 秒,狀態列就會顯示過時文字。請避免在大型儲存庫中使用 git status,並將耗時操作的結果快取到以 session_id 為索引的檔案中。
如何在每台伺服器上顯示不同的狀態列?
保留一個指令碼,讓它讀取電腦資訊。上述指令碼會以 hostname -s 作為 fallback,輸出 $HOSTNAME,因此將同一個檔案複製到每台伺服器後,每台都能正確標示自身;checksum 顏色技巧也會為每個 hostname 指定專屬色彩。如果某台伺服器需要不同的配置,請在該伺服器上所使用之儲存庫的專案設定中加入 statusLine 區塊,因為專案設定會優先套用於該目錄,覆寫使用者設定。