SSD Nodes Learn 🎉 VPS dari $5.50/bln
Panduan Matt ConnorOleh Matt Connor · Dikemas kini 2026-08-13

Cara Konfigurasi Claude Code Statusline di VPS

Ketahui cara menambah statusline pada Claude Code untuk memaparkan hostname, direktori, dan cawangan git. Elakkan kesilapan pelayan dengan skrip status sesi yang selamat.

Makna paparan statusline Claude Code

Statusline Claude Code ialah baris di bawah prompt yang memaparkan output skrip yang anda tulis. Anda perlu menambah blok statusLine ke dalam settings.json dan menghalakannya kepada sesuatu arahan. Claude Code akan menjalankan arahan tersebut, menghantar status sesi kepadanya sebagai JSON melalui standard input, dan mencetak apa sahaja yang ditulis oleh arahan tersebut ke standard output.

Itu sahaja kontraknya. Skrip anda membaca JSON pada stdin dan mencetak teks pada stdout. Ia berjalan pada mesin anda dan tiada apa-apa yang dicetaknya dihantar kepada model, jadi ia tidak menggunakan sebarang token.

Pada komputer riba dengan satu projek, ini hanyalah hiasan. Pada tiga pelayan, ia merupakan langkah keselamatan. Setiap sesi Claude Code kelihatan sama dalam setiap terminal, jadi empat tetingkap SSH tanpa label adalah punca migrasi tersalah masuk ke pelayan yang salah. Statusline yang bermula dengan hostname akan menamatkan risiko kesilapan tersebut.

Lokasi tetapan statusLine dalam settings.json

Letakkan tetapan ini dalam tetapan pengguna anda di ~/.claude/settings.json, yang akan terpakai untuk setiap projek pada mesin tersebut. Tetapan projek di .claude/settings.json di dalam repositori juga boleh digunakan, dan ia akan mengatasi tetapan lain bagi direktori tersebut.

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

type sentiasa bernilai "command". Nilai command dijalankan melalui shell, jadi ia boleh berupa laluan skrip atau arahan biasa. Pastikan sambungan berfungsi sebelum anda menulis sebarang skrip:

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

Mulakan Claude Code dan hantar satu mesej. Bar di bawah prompt kini memaparkan nama hos pendek pelayan tersebut. Jika ia kekal kosong, masalahnya terletak pada tetapan atau dialog kepercayaan, bukan pada skrip anda. Baca "Mengapa statusline kekal kosong" di bawah.

Tiga kunci pilihan tersedia setakat Ogos 2026. padding menambah jarak mendatar dalam aksara dan nilai lalainya ialah 0. refreshInterval menjalankan semula arahan setiap N saat sebagai tambahan kepada pencetus biasa, dengan nilai minimum 1, yang hanya diperlukan apabila baris tersebut memaparkan jam atau sesuatu yang berubah semasa sesi melahu. hideVimModeIndicator menyekat teks -- INSERT -- terbina dalam apabila skrip anda sendiri sudah memaparkan mod vim.

Apakah data yang diterima oleh skrip statusline?

Jangan percaya senarai medan yang anda baca di mana-mana, termasuk halaman ini. Tangkap objek sebenar yang dihantar oleh versi anda. Tulis skrip sementara yang menyimpan stdin ke dalam fail:

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

Halakan statusLine.command ke fail tersebut, mulakan sesi, dan hantar satu mesej. Bar tersebut membaca captured. Sekarang lihat apa yang sampai:

jq . /tmp/statusline-input.json

Anda mempunyai bentuk yang tepat untuk binaan anda, dan anda boleh mengulanginya pada bila-bila masa apabila kemas kini mengubah sesuatu.

Bahagian yang stabil, seperti yang didokumenkan pada Ogos 2026, adalah objek bersarang dan bukannya kunci rata. model memegang id dan display_name. workspace memegang current_dir dan project_dir: current_dir ialah tempat sesi berada sekarang, project_dir ialah tempat ia dilancarkan, dan kedua-duanya berbeza sebaik sahaja direktori kerja berubah di pertengahan sesi. cwd peringkat atas membawa nilai yang sama seperti workspace.current_dir. context_window memegang kiraan token serta used_percentage yang telah dikira terlebih dahulu. cost memegang total_cost_usd dan pembilang tempoh. session_id adalah stabil sepanjang hayat sesi dan unik merentas sesi, yang penting untuk caching kemudian.

Tiga peraturan memastikan skrip kekal berfungsi merentas perubahan skema.

Sesetengah kunci tiada, bukan null. vim, agent, pr, worktree dan effort hanya muncul apabila ciri yang sepadan aktif. Membaca .vim.mode dengan jq -r semasa mod vim dimatikan akan mencetak rentetan literal null, dan bar anda menunjukkan null kepada pembaca. Tambahkan // empty pada setiap pemilih, supaya kunci yang hilang tidak mencetak apa-apa.

Sesetengah nilai adalah null pada peringkat awal. context_window.used_percentage dan context_window.current_usage adalah null sebelum respons API pertama, dan current_usage kembali kepada null selepas /compact sehingga panggilan seterusnya mengisinya semula. Oleh itu, peratusan konteks pada bar memerlukan // 0, atau ia akan membaca null untuk beberapa saat pertama setiap sesi. Sebelum anda meletakkan nombor itu pada bar, adalah berguna untuk mengetahui bagaimana tetingkap konteks sebenarnya diisi.

Cawangan git tidak ada dalam JSON. Tiada medan yang melaporkannya. Sebarang cawangan pada bar anda datang daripada skrip anda yang menjalankan git sendiri.

Skrip statusline yang merosot secara anggun dan bukannya terhenti

Ini ialah versi salin-tampal. Skrip ini mencetak nama hos, direktori kerja, cawangan git dan nama model. Setiap medan mempunyai sandaran (fallback), jadi objek JSON yang kosong sekalipun masih menghasilkan baris yang boleh digunakan.

#!/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"

Setiap bacaan melalui field, yang menambah // empty, jadi kunci yang dinamakan semula atau dibuang akan menghasilkan rentetan kosong dan baris seterusnya akan membekalkan nilai lalai. Direktori akan disandarkan daripada workspace.current_dir kepada cwd kepada $PWD. Cawangan diambil daripada git -C "$DIR" dan bukannya git kosong, jadi cawangan sentiasa sepadan dengan direktori yang dipaparkan oleh bar tersebut.

Simpan skrip tersebut, kemudian jadikan ia boleh laksana:

chmod +x ~/.claude/statusline.sh

Bit laksana (execute bit) adalah wajib. Claude Code menjalankan perintah melalui shell, jadi skrip tanpa +x akan gagal dengan Permission denied, tidak menghasilkan stdout, dan baris tersebut kekal kosong tanpa ralat yang kelihatan.

jq menghuraikan JSON pada baris perintah dan tidak dipasang secara lalai pada pelayan Ubuntu baharu:

sudo apt update && sudo apt install -y jq

Kemudian, halakan tetapan kepada skrip tersebut menggunakan blok settings.json pertama di atas.

Uji skrip sebelum anda mempercayainya

Jalankan skrip tersebut sebanyak dua kali secara manual. Pertama, gunakan objek sesi biasa:

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

Anda akan mendapat nama hos, diikuti dengan /srv/api, kemudian Opus. Tiada cawangan (branch) yang dipaparkan, kerana /srv/api pada mesin anda mungkin bukan repositori git.

Kedua, lakukan ujian degradasi, iaitu ujian yang sering diabaikan oleh pengguna:

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

Objek kosong merupakan senario terburuk yang boleh berlaku akibat perubahan skema. Baris tersebut masih mencetak: nama hos, direktori semasa daripada $PWD, dan perkataan claude di tempat nama model sepatutnya berada. Tiada apa-apa yang terhenti (crash) dan tiada apa-apa yang mencetak null. Skrip yang melepasi ujian ini mampu bertahan jika sesuatu medan dinamakan semula, kerana bagi skrip anda, medan yang dinamakan semula dan medan yang hilang dianggap sebagai peristiwa yang sama.

Apa yang sepatutnya anda lihat

Statusline dipaparkan pada barisnya sendiri di atas lencana pengaki (footer badges) terbina dalam dan tidak menggantikannya. Pada persediaan yang berfungsi, ia terdiri daripada satu baris: nama hos pendek dalam warna sian, diikuti direktori kerja dengan direktori rumah anda diringkaskan kepada ~, kemudian nama cawangan dalam warna kuning apabila direktori tersebut merupakan repositori git, dan seterusnya nama model yang dimalapkan. Sesuatu yang hampir dengan web-01 ~/api main Opus, dengan keempat-empat bahagian tersebut berwarna.

Baris ini menjalankan semula skrip anda apabila sesi bermula, termasuk penyambungan semula (resume), apabila mesej pembantu baharu tiba, selepas /compact selesai, apabila mod kebenaran berubah, apabila mod vim bertukar, dan pada detik refreshInterval jika anda menetapkannya. Kemas kini dinyahlantun (debounced) pada 300 ms, jadi perubahan yang berlaku secara serentak hanya akan menjalankan skrip sekali sahaja. Bar tersebut disembunyikan semasa autolengkap, menu bantuan dan gesaan kebenaran, kemudian dipaparkan semula.

Mengapa hostname perlu diletakkan di hadapan

Apabila anda menjalankan ejen pada lebih daripada satu pelayan, terminal adalah satu-satunya petunjuk lokasi anda, dan terminal sering memberikan maklumat yang salah. Buka sambungan ssh kedua dari dalam anak tetingkap tmux dan tajuk tetingkap sering mengekalkan nama lama, kerana tajuk tersebut ditetapkan oleh shell yang tidak mengesan perubahan lokasi. Biarkan Claude Code berjalan dalam sesi tmux yang dipisahkan pada VPS dan sambung semula sehari kemudian, tiada apa-apa pada skrin yang membezakan pelayan binaan (build server) daripada kotak pengeluaran (production box).

Baris status adalah berbeza kerana ia dirender oleh Claude Code sendiri, bagi setiap sesi, daripada data yang disimpan oleh sesi tersebut. Ia tidak boleh diwarisi daripada anak tetingkap yang salah atau dibiarkan lapuk oleh gesaan shell yang tidak dikemas kini. Apa yang dipaparkannya ialah kotak tempat ejen tersebut menulis fail.

Berikan setiap pelayan warna tersendiri supaya anda mengenalinya sebelum membacanya. Dua baris, diletakkan di atas tugasan LINE=:

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

Kemudian gunakan ${HOST_COLOR} sebagai ganti ${CYAN}. cksum mencetak checksum bagi hostname, jadi nama tertentu sentiasa dipetakan kepada warna yang sama dalam julat 31 hingga 36, iaitu daripada merah hingga sian. Salin skrip yang sama ke setiap kotak dan setiap satu akan melabelkan dirinya sendiri.

Direktori mendapat tempatnya atas sebab yang sama. /srv/api dan /srv/api-staging hanya dipisahkan oleh satu ketukan kekunci dalam arahan ssh, namun kesannya boleh menyebabkan insiden yang besar. Model dan cawangan (branch) adalah dua lagi maklumat yang berbaloi dengan ruang yang digunakan: model memberitahu anda sesi mana yang anda sambung semula, dan cawangan memberitahu anda sama ada ejen tersebut akan melakukan komit pada main.

Skrin kecil menjadikan semua ini lebih jelas, kerana tiada tajuk tetingkap untuk dijadikan sandaran. Jika itu adalah persediaan anda, lihat mengendalikan Claude Code daripada telefon.

Pastikan skrip berjalan pantas

Skrip anda berjalan pada setiap mesej pembantu, dan Claude Code membatalkan pelaksanaan yang sedang berjalan apabila kemas kini baharu tiba. Oleh itu, skrip yang perlahan akan memaparkan teks yang lapuk atau tiada teks langsung.

Setiap panggilan jq mengambil masa beberapa milisaat. git ialah bahagian yang menjadi perlahan: git status dalam repositori yang besar dengan cache sejuk mengambil masa ratusan milisaat. Skrip di atas sengaja mengelakkan git status dan memanggil git branch --show-current, yang membaca .git/HEAD dan kembali serta-merta.

Jika anda menambah sesuatu yang lebih berat, simpan dalam fail dan segarkannya setiap beberapa saat. Gunakan sesi sebagai kunci fail tersebut:

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

Gunakan session_id, bukan $$. $$ ialah ID proses skrip anda, yang berbeza pada setiap panggilan, jadi cache yang dikunci dengannya tidak akan pernah ditemui dan anda menanggung kos penuh setiap kali. session_id adalah stabil untuk keseluruhan sesi dan berbeza antara sesi, jadi dua sesi Claude Code dalam dua repositori berbeza tidak boleh membaca nama cawangan yang dicache oleh satu sama lain.

Satu lagi had yang perlu diketahui: tput cols tidak berfungsi di dalam skrip statusline. Claude Code menangkap output tersebut dan bukannya menyambungkan skrip anda ke terminal, jadi pengesanan lebar tidak mempunyai apa-apa untuk diukur. Claude Code menetapkan pemboleh ubah persekitaran COLUMNS dan LINES sebelum menjalankan arahan, dalam v2.1.153 dan seterusnya, jadi baca $COLUMNS apabila anda perlu menentukan jumlah teks yang ingin dicetak.

Mengapa bar status kekal kosong

Tiada apa-apa yang dipaparkan. Semak bit laksana (execute bit) dengan ls -l ~/.claude/statusline.sh, kemudian jalankan skrip secara manual menggunakan input olok-olok di atas. Jika ia mencetak baris pada shell tetapi tidak dalam Claude Code, mulakan dengan claude --debug, yang merekodkan kod keluar (exit code) dan stderr bagi larian bar status pertama dalam sesi tersebut.

Log nyahpepijat menyatakan Status line command skipped: workspace trust not accepted. Bar status melaksanakan arahan shell, jadi ia berada di sebalik pintu gerbang kepercayaan ruang kerja (workspace trust gate) yang sama seperti cangkuk (hooks). Selagi anda tidak menerima dialog kepercayaan untuk direktori tersebut, arahan itu tidak akan berjalan. Ini perkara biasa pada VPS, di mana setiap klon baharu merupakan direktori yang belum pernah dilihat oleh Claude Code. Mulakan semula Claude Code dalam direktori tersebut dan terima dialog berkenaan.

Semuanya kosong dan disableAllHooks ditetapkan. "disableAllHooks": true dalam settings.json turut melumpuhkan bar status, kerana ia menggunakan pintu gerbang pelaksanaan shell yang sama. Buang tetapan tersebut atau tetapkan kepada false.

Baris mencetak null. Pemilih jq mencapai kunci yang tiada atau null, dan jq -r mencetak null sebagai empat aksara null. Tambahkan // empty untuk teks dan // 0 untuk nombor.

Baris menjadi kosong sejurus selepas anda menyunting skrip. Arahan yang keluar dengan kod bukan sifar, atau tidak mencetak apa-apa, akan mengosongkan baris tersebut. Punca biasa ialah baris terakhir seperti [ -n "$BRANCH" ] && LINE="...", yang keluar dengan kod 1 apabila cawangan (branch) kosong dan membawa kod keluar keseluruhan skrip bersamanya. Pastikan printf berada di kedudukan terakhir, atau tambahkan exit 0.

Kod escape dipaparkan sebagai teks literal seperti \e]8;; pada bar. Gunakan printf '%b' sebagai ganti echo -e. Pautan OSC 8 yang boleh diklik juga memerlukan terminal yang menyokongnya, dan tmux atau SSH mungkin membuang jujukan tersebut, jadi warna biasa adalah pilihan yang lebih selamat pada mesin jauh.

Bahagian kanan bar terpotong. Pemberitahuan sistem dan pembilang token mod verbose berkongsi baris yang sama dari arah kanan, dan terminal yang sempit akan menyebabkan pertindihan hilang. Pastikan output anda ringkas. Untuk pengiraan penggunaan yang sebenar dan bukannya sekadar nombor pada bar, lihat cara Claude Code mengira token.

FAQ

Di manakah tetapan statusline Claude Code disimpan?

Dalam settings.json, sebagai blok statusLine dengan type ditetapkan kepada "command" dan command ditetapkan kepada laluan skrip atau arahan shell. Tetapan pengguna berada di ~/.claude/settings.json dan terpakai untuk setiap projek pada mesin tersebut. Tetapan projek berada di .claude/settings.json di dalam repositori dan akan mengatasi tetapan lain bagi direktori tersebut. Tetapan dimuat semula secara automatik, tetapi perubahan hanya akan kelihatan pada pencetus kemas kini seterusnya, seperti mesej anda yang berikutnya.

Mengapakah statusline Claude Code saya kosong?

Empat punca merangkumi hampir semua kes. Skrip tersebut tiada bit execute, jadi shell mengembalikan Permission denied dan tiada apa-apa yang sampai ke stdout. Dialog kepercayaan ruang kerja tidak pernah diterima, dan claude --debug mencatat Status line command skipped: workspace trust not accepted. disableAllHooks adalah true, yang melumpuhkan statusline di bawah sekatan yang sama. Atau skrip keluar dengan status bukan sifar, yang mengosongkan baris tersebut. Uji secara manual dahulu: echo '{}' | ~/.claude/statusline.sh mestilah mencetak sesuatu.

Adakah JSON statusline menyertakan cawangan git?

Tidak. JSON tersebut membawa status sesi seperti model, direktori ruang kerja, nombor tetingkap konteks dan kos. Tiada apa-apa di dalamnya yang melaporkan git. Cawangan pada bar anda datang daripada skrip anda sendiri yang memanggil git branch --show-current. Hantarkan direktori daripada JSON dengan git -C "$DIR", supaya cawangan sentiasa sepadan dengan direktori yang dipaparkan oleh bar tersebut.

Adakah statusline menggunakan token atau melambatkan sesi?

Ia tidak menggunakan sebarang token, kerana skrip berjalan secara setempat dan outputnya tidak pernah dihantar kepada model. Kelajuan adalah tanggungjawab anda. Arahan tersebut berjalan pada setiap mesej pembantu dengan debounce 300 ms, dan Claude Code membatalkan pelaksanaan yang sedang berjalan apabila kemas kini baharu tiba, jadi skrip yang mengambil masa satu saat penuh akan memaparkan teks yang lapuk. Elakkan git status dalam repositori yang besar, dan cache apa-apa yang perlahan dalam fail yang dikunci pada session_id.

Bagaimanakah cara untuk memaparkan statusline yang berbeza pada setiap pelayan?

Gunakan satu skrip dan biarkan ia membaca mesin tersebut. Skrip di atas mencetak $HOSTNAME dengan hostname -s sebagai sandaran, jadi fail yang sama yang disalin ke setiap kotak akan melabelkan setiap satu dengan betul, dan helah warna checksum memberikan setiap hostname warnanya yang tersendiri. Jika satu pelayan memerlukan susun atur yang berbeza, letakkan blok statusLine dalam tetapan projek repositori yang anda kerjakan pada kotak tersebut, memandangkan tetapan projek mengatasi tetapan pengguna untuk direktori itu.