วิธีตั้งค่า statusline ใน Claude Code บน VPS ให้แสดงข้อมูล
เรียนรู้วิธีตั้งค่า statusLine ใน Claude Code เพื่อแสดง hostname, directory และ git branch บน VPS ป้องกันการพิมพ์คำสั่งผิดพลาดในเซิร์ฟเวอร์ด้วยการใช้สคริปต์ดึงค่าผ่าน stdin
สิ่งที่แสดงบน statusline ของ Claude Code
statusline ของ Claude Code คือแถวที่อยู่ใต้บรรทัดรับคำสั่ง (prompt) ซึ่งจะแสดงผลลัพธ์จากสคริปต์ที่คุณเขียนขึ้น คุณสามารถเพิ่มบล็อก statusLine เข้าไปใน settings.json และระบุคำสั่งที่ต้องการให้ทำงาน Claude Code จะรันคำสั่งนั้น โดยส่งสถานะของเซสชันในรูปแบบ JSON เข้าทาง standard input และพิมพ์สิ่งที่คำสั่งนั้นส่งออกมาทาง standard output
นี่คือข้อตกลงการทำงานทั้งหมด สคริปต์ของคุณจะอ่าน JSON จาก stdin และพิมพ์ข้อความออกทาง stdout สคริปต์นี้รันบนเครื่องของคุณเองและไม่มีข้อมูลใดที่พิมพ์ออกมาถูกส่งไปยังโมเดล ดังนั้นจึงไม่มีการใช้โทเค็น
บนแล็ปท็อปที่มีโปรเจกต์เดียว สิ่งนี้อาจเป็นเพียงการตกแต่ง แต่บนเซิร์ฟเวอร์ 3 เครื่อง มันคือระบบป้องกันความปลอดภัย ทุกเซสชันของ Claude Code จะมีหน้าตาเหมือนกันในทุกเทอร์มินัล ดังนั้นการเปิดหน้าต่าง SSH 4 บานโดยไม่มีป้ายกำกับจึงเป็นสาเหตุที่ทำให้การย้ายข้อมูลผิดพลาดไปยังเครื่องที่ไม่ถูกต้อง การมี statusline ที่ขึ้นต้นด้วย hostname จะช่วยป้องกันความผิดพลาดประเภทนี้ได้
ตำแหน่งของค่าการตั้งค่า statusLine ใน settings.json
ให้ใส่ค่านี้ไว้ในการตั้งค่าผู้ใช้ที่ ~/.claude/settings.json ซึ่งจะมีผลกับทุกโปรเจกต์บนเครื่องนั้น สำหรับการตั้งค่าโปรเจกต์ที่ .claude/settings.json ภายใน repository ก็สามารถทำได้เช่นกัน และจะมีลำดับความสำคัญสูงกว่าหากอยู่ในไดเรกทอรีนั้น
{
"statusLine": {
"type": "command",
"command": "~/.claude/statusline.sh"
}
}type จะเป็น "command" เสมอ ค่าของ command จะถูกรันผ่าน shell ดังนั้นจึงสามารถเป็น path ของสคริปต์หรือคำสั่งทั่วไปก็ได้ ให้ทดสอบว่าการเชื่อมต่อทำงานได้จริงก่อนที่จะเขียนสคริปต์ใดๆ:
{
"statusLine": {
"type": "command",
"command": "hostname -s"
}
}เริ่มการทำงานของ Claude Code และส่งข้อความหนึ่งครั้ง แถบด้านล่างช่องกรอกคำสั่งจะแสดงชื่อโฮสต์แบบย่อของเซิร์ฟเวอร์ หากแถบนั้นยังว่างเปล่า แสดงว่าปัญหาอยู่ที่การตั้งค่าหรือกล่องโต้ตอบการยืนยันความเชื่อถือ (trust dialog) ไม่ใช่ที่สคริปต์ของคุณ โปรดอ่านหัวข้อ "ทำไม statusline ถึงยังว่างเปล่า" ด้านล่าง
มีคีย์เสริม 3 รายการ ณ เดือนสิงหาคม 2026 ดังนี้ padding ใช้เพิ่มระยะห่างแนวนอนโดยนับเป็นจำนวนตัวอักษร โดยมีค่าเริ่มต้นเป็น 0 ส่วน refreshInterval จะรันคำสั่งซ้ำทุกๆ N วินาที นอกเหนือไปจากทริกเกอร์ปกติ โดยมีค่าขั้นต่ำอยู่ที่ 1 ซึ่งคุณควรใช้เฉพาะในกรณีที่บรรทัดดังกล่าวแสดงนาฬิกาหรือข้อมูลที่มีการเปลี่ยนแปลงในขณะที่เซสชันไม่ได้ใช้งาน และ hideVimModeIndicator ใช้สำหรับปิดข้อความ -- INSERT -- ที่มีมาให้ในตัว เมื่อสคริปต์ของคุณแสดงผล vim mode ด้วยตัวเองอยู่แล้ว
สคริปต์ statusline ได้รับข้อมูลอะไรบ้าง
อย่าเชื่อรายการฟิลด์ที่คุณอ่านจากที่ใดก็ตาม รวมถึงหน้านี้ ให้จับข้อมูลออบเจกต์จริงที่เวอร์ชันของคุณส่งออกมา โดยเขียนสคริปต์ชั่วคราวเพื่อบันทึก 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 คือออบเจกต์แบบซ้อนกันแทนที่จะเป็นคีย์แบบแบน model เก็บ id และ display_name ไว้ ส่วน workspace เก็บ current_dir และ project_dir ไว้: current_dir คือตำแหน่งที่เซสชันอยู่ ณ ปัจจุบัน project_dir คือตำแหน่งที่เซสชันถูกเปิดใช้งาน และทั้งสองค่าจะต่างกันเมื่อมีการเปลี่ยน working directory ระหว่างเซสชัน ส่วน cwd ในระดับบนสุดจะมีค่าเดียวกับ workspace.current_dir โดย context_window จะเก็บจำนวน token บวกกับ used_percentage ที่คำนวณไว้ล่วงหน้า cost เก็บ total_cost_usd และตัวนับระยะเวลาไว้ ส่วน session_id จะคงที่ตลอดอายุของเซสชันและไม่ซ้ำกันในแต่ละเซสชัน ซึ่งมีความสำคัญสำหรับการทำ caching ในภายหลัง
กฎ 3 ข้อที่จะช่วยให้สคริปต์ทำงานได้แม้มีการเปลี่ยนแปลง schema
บางคีย์อาจไม่มีอยู่จริง ไม่ใช่แค่เป็นค่า null vim, agent, pr, worktree และ effort จะปรากฏเฉพาะเมื่อฟีเจอร์ที่เกี่ยวข้องทำงานอยู่เท่านั้น การอ่าน .vim.mode ด้วย jq -r ในขณะที่ vim mode ปิดอยู่ จะแสดงผลเป็นสตริงตัวอักษร null และแถบสถานะของคุณจะแสดง null ให้ผู้ใช้เห็น ให้เพิ่ม // empty ต่อท้ายทุก selector เพื่อให้คีย์ที่หายไปไม่แสดงผลใดๆ ออกมาเลย
บางค่าอาจเป็น null ในช่วงแรก context_window.used_percentage และ context_window.current_usage จะเป็น null ก่อนที่จะมีการตอบกลับจาก API ครั้งแรก และ current_usage จะกลับเป็น null หลังจาก /compact จนกว่าการเรียกครั้งถัดไปจะเติมข้อมูลเข้าไปใหม่ ดังนั้นเปอร์เซ็นต์ context บนแถบสถานะจึงจำเป็นต้องใช้ // 0 มิฉะนั้นมันจะอ่านค่าเป็น null ในช่วงไม่กี่วินาทีแรกของทุกเซสชัน ก่อนที่คุณจะนำตัวเลขนั้นไปแสดงบนแถบสถานะ การทำความเข้าใจ ว่า context window เติมข้อมูลอย่างไร จะช่วยได้มาก
git branch ไม่ได้อยู่ใน JSON ไม่มีฟิลด์ใดรายงานค่านี้ branch ใดๆ บนแถบสถานะของคุณมาจากการที่สคริปต์ของคุณรันคำสั่ง git ด้วยตัวเอง
สคริปต์แสดงสถานะที่ลดระดับการทำงานแทนการหยุดทำงาน
นี่คือเวอร์ชันสำหรับคัดลอกและวาง สคริปต์นี้จะแสดง hostname, ไดเรกทอรีปัจจุบัน, branch ของ 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 ตามลำดับ ส่วน branch จะดึงมาจาก git -C "$DIR" แทนที่จะใช้ git โดยตรง เพื่อให้ branch ตรงกับไดเรกทอรีที่แถบสถานะแสดงอยู่เสมอ
บันทึกไฟล์แล้วทำให้เป็นไฟล์ที่รันได้:
chmod +x ~/.claude/statusline.shการตั้งค่า execute bit เป็นสิ่งที่จำเป็น หาก Claude Code รันคำสั่งผ่าน shell แล้วสคริปต์ไม่มี +x จะทำให้เกิดข้อผิดพลาด Permission denied ส่งผลให้ไม่มี stdout ออกมา และแถวสถานะจะว่างเปล่าโดยไม่มีข้อความแจ้งเตือนที่มองเห็นได้
jq ใช้สำหรับประมวลผล JSON บนบรรทัดคำสั่ง ซึ่งไม่ได้ถูกติดตั้งมาพร้อมกับ Ubuntu server รุ่นเริ่มต้น:
sudo apt update && sudo apt install -y jqจากนั้นให้ชี้การตั้งค่าไปยังสคริปต์ โดยใช้บล็อก settings.json แรกที่ระบุไว้ด้านบน
ทดสอบสคริปต์ก่อนใช้งานจริง
ให้รันสคริปต์ด้วยตนเอง 2 ครั้ง ครั้งแรกให้ใช้ object ของ session ปกติ:
echo '{"model":{"display_name":"Opus"},"workspace":{"current_dir":"/srv/api"},"session_id":"t1"}' | ~/.claude/statusline.shคุณจะได้ชื่อโฮสต์ ตามด้วย /srv/api และ Opus จะไม่มี branch ปรากฏขึ้น เนื่องจาก /srv/api บนเครื่องของคุณอาจไม่ใช่ git repository
ครั้งที่สองคือการทดสอบการเสื่อมสภาพ (degradation test) ซึ่งเป็นส่วนที่คนมักข้ามไป:
echo '{}' | ~/.claude/statusline.shobject ที่ว่างเปล่าคือกรณีที่เลวร้ายที่สุดที่การเปลี่ยนแปลง schema อาจส่งผลต่อคุณ บรรทัดดังกล่าวยังคงแสดงผล: ชื่อโฮสต์, ไดเรกทอรีปัจจุบันจาก $PWD และคำว่า claude ในตำแหน่งที่ควรจะเป็นชื่อโมเดล ไม่มีส่วนใดที่ทำงานผิดพลาดและไม่มีการแสดงผล null สคริปต์ที่ผ่านการทดสอบนี้จะสามารถทำงานได้แม้มีการเปลี่ยนชื่อฟิลด์ เพราะสำหรับสคริปต์ของคุณแล้ว การเปลี่ยนชื่อฟิลด์และการที่ฟิลด์หายไปถือเป็นเหตุการณ์เดียวกัน
สิ่งที่คุณควรเห็น
บรรทัดสถานะจะแสดงผลในแถวของตัวเองเหนือป้ายกำกับส่วนท้ายที่มาพร้อมกับโปรแกรม และจะไม่เข้าไปแทนที่ป้ายกำกับเหล่านั้น ในการตั้งค่าที่ทำงานได้ปกติ บรรทัดนี้จะเป็นแถวเดียว ประกอบด้วย: ชื่อโฮสต์แบบย่อในสีฟ้า, ตามด้วยไดเรกทอรีปัจจุบันโดยที่ไดเรกทอรีโฮมของคุณจะถูกย่อเป็น ~, จากนั้นเป็นชื่อ branch ในสีเหลืองเมื่อไดเรกทอรีนั้นเป็น git repository และปิดท้ายด้วยชื่อโมเดลในสีจาง คุณควรเห็นผลลัพธ์ที่ใกล้เคียงกับ web-01 ~/api main Opus โดยมีองค์ประกอบทั้งสี่ส่วนแสดงสีตามที่กำหนด
แถบสถานะจะรันสคริปต์ของคุณใหม่เมื่อเริ่มเซสชัน รวมถึงการ resume, เมื่อมีข้อความใหม่จากผู้ช่วย, หลังจาก /compact ทำงานเสร็จสิ้น, เมื่อโหมดสิทธิ์การใช้งานเปลี่ยนไป, เมื่อมีการสลับโหมด vim และเมื่อถึงรอบ refreshInterval หากคุณตั้งค่าไว้ การอัปเดตจะถูกหน่วงเวลาไว้ที่ 300 ms เพื่อป้องกันการรันสคริปต์ซ้ำซ้อนหากมีการเปลี่ยนแปลงเกิดขึ้นอย่างรวดเร็วต่อเนื่อง แถบสถานะจะซ่อนตัวระหว่างการทำ autocomplete, เมนูช่วยเหลือ และการแจ้งเตือนขอสิทธิ์การใช้งาน จากนั้นจะกลับมาแสดงผลอีกครั้ง
เหตุผลที่ต้องวาง hostname ไว้ลำดับแรก
เมื่อคุณรันเอเจนต์บนเซิร์ฟเวอร์มากกว่าหนึ่งเครื่อง เทอร์มินัลเป็นสิ่งเดียวที่บอกคุณว่าคุณอยู่ที่ไหน แต่เทอร์มินัลมักหลอกลวงได้ หากคุณเปิดการเชื่อมต่อ ssh ที่สองจากภายใน tmux pane ชื่อหน้าต่างมักจะยังคงเป็นชื่อเดิม เพราะชื่อนั้นถูกกำหนดโดยเชลล์ที่ไม่ทราบว่ามีการย้ายตำแหน่ง หากคุณทิ้ง Claude Code ให้รันอยู่ใน tmux session แบบ detached บน VPS แล้วกลับมาเชื่อมต่อใหม่ในวันถัดไป จะไม่มีสิ่งใดบนหน้าจอที่แยกความแตกต่างระหว่างเซิร์ฟเวอร์ build กับเครื่อง production ได้เลย
แถบสถานะ (statusline) นั้นแตกต่างออกไปเพราะถูกเรนเดอร์โดยตัว Claude Code เองในแต่ละ session จากข้อมูลที่ session นั้นถืออยู่ มันจึงไม่สามารถถูกสืบทอดมาจาก pane ที่ผิดพลาดหรือค้างอยู่จาก shell prompt ที่ไม่ได้รีเฟรช สิ่งที่แสดงบนแถบสถานะคือเครื่องที่เอเจนต์กำลังเขียนไฟล์อยู่จริง
กำหนดสีให้แต่ละเซิร์ฟเวอร์เพื่อให้คุณจดจำได้ก่อนที่จะอ่านข้อความ สองบรรทัดนี้ให้วางไว้เหนือการกำหนดค่า LINE=:
CODE=$(printf '%s' "$HOST" | cksum | cut -d' ' -f1)
HOST_COLOR=$(printf '\033[%dm' "$((31 + CODE % 6))")จากนั้นใช้ ${HOST_COLOR} แทนที่ ${CYAN} โดย cksum จะพิมพ์ค่า checksum ของ hostname ออกมา ทำให้ชื่อที่กำหนดจะจับคู่กับสีเดิมเสมอในช่วง 31 ถึง 36 ซึ่งเป็นสีแดงถึงสีฟ้า cyan ให้คัดลอกสคริปต์เดียวกันนี้ไปยังทุกเครื่อง แล้วแต่ละเครื่องจะระบุตัวตนด้วยสีของตัวเอง
ไดเรกทอรีมีความสำคัญด้วยเหตุผลเดียวกัน /srv/api และ /srv/api-staging อยู่ห่างกันเพียงหนึ่งปุ่มกดในคำสั่ง ssh แต่ส่งผลกระทบต่อเหตุการณ์ที่แตกต่างกันอย่างสิ้นเชิง โมเดลและ branch คืออีกสองสิ่งที่คุ้มค่าที่จะใช้พื้นที่แสดงผล: โมเดลจะบอกคุณว่าคุณกลับมาใช้งาน session ไหน และ branch จะบอกคุณว่าเอเจนต์กำลังจะ commit ลงบน main หรือไม่
หน้าจอขนาดเล็กทำให้สิ่งเหล่านี้ชัดเจนยิ่งขึ้น เนื่องจากไม่มีชื่อหน้าต่างให้พึ่งพา หากนั่นคือการตั้งค่าของคุณ โปรดดู การใช้งาน Claude Code จากโทรศัพท์
รักษาความเร็วของสคริปต์
สคริปต์ของคุณจะทำงานในทุกข้อความของผู้ช่วย และ Claude Code จะยกเลิกการทำงานที่ค้างอยู่เมื่อมีการอัปเดตใหม่เข้ามา ดังนั้นสคริปต์ที่ทำงานช้าจะแสดงข้อความที่ล้าสมัยหรือไม่แสดงข้อความเลย
การเรียกใช้ jq แต่ละครั้งใช้เวลาเพียงไม่กี่มิลลิวินาที ส่วน git คือส่วนที่ทำให้การทำงานช้าลง โดย git status ใน repository ขนาดใหญ่ที่มี cache ว่างเปล่าอาจใช้เวลาหลายร้อยมิลลิวินาที สคริปต์ด้านบนจงใจหลีกเลี่ยง git status และเลือกใช้ git branch --show-current แทน ซึ่งจะอ่าน .git/HEAD และส่งค่ากลับทันที
หากคุณต้องการเพิ่มการทำงานที่หนักขึ้น ให้เก็บไว้ในไฟล์ cache และรีเฟรชทุกๆ สองสามวินาที โดยใช้ session เป็นคีย์สำหรับไฟล์:
CACHE="/tmp/statusline-$(field '.session_id')"ให้ใช้ session_id แทน $$ เพราะ $$ คือ process ID ของสคริปต์คุณ ซึ่งจะเปลี่ยนไปทุกครั้งที่เรียกใช้ ทำให้ cache ที่อ้างอิงจากค่านี้ไม่เคยถูกใช้งานจริงและคุณต้องเสียเวลาประมวลผลเต็มจำนวนทุกครั้ง ส่วน session_id จะคงที่ตลอดทั้ง session และแตกต่างกันในแต่ละ session ดังนั้น Claude Code สอง session ในสอง repository จะไม่สามารถอ่านชื่อ branch ที่ cache ไว้ของกันและกันได้ การแยกส่วนของ session ถูกออกแบบมาให้เป็นเช่นนั้น ดังนั้นการส่งต่องานระหว่างกันจึงต้องทำผ่านขั้นตอนที่ตั้งใจไว้ ซึ่งเป็นจุดประสงค์ของ การส่งข้อความจาก Claude Code session หนึ่งไปยังอีก session หนึ่ง
ข้อจำกัดอีกประการที่ควรทราบคือ tput cols ไม่สามารถใช้งานภายในสคริปต์ statusline ได้ เนื่องจาก Claude Code จะดักจับ output แทนการเชื่อมต่อสคริปต์ของคุณเข้ากับ terminal ทำให้การตรวจจับความกว้างไม่มีค่าให้วัดผล ทั้งนี้ Claude Code จะตั้งค่าตัวแปรสภาพแวดล้อม COLUMNS และ LINES ก่อนรันคำสั่งในเวอร์ชัน v2.1.153 เป็นต้นไป ดังนั้นให้ใช้ $COLUMNS เมื่อคุณต้องการตัดสินใจว่าจะแสดงผลมากน้อยเพียงใด
เหตุใดบรรทัดสถานะจึงว่างเปล่า
ไม่ปรากฏข้อมูลใดๆ เลย ให้ตรวจสอบบิตการทำงาน (execute bit) ด้วย ls -l ~/.claude/statusline.sh จากนั้นลองรันสคริปต์ด้วยตนเองโดยใช้ข้อมูลอินพุตจำลองตามที่ระบุไว้ข้างต้น หากสคริปต์แสดงผลลัพธ์ที่เชลล์ได้แต่ไม่แสดงใน Claude Code ให้เริ่มต้นด้วย claude --debug ซึ่งจะบันทึก exit code และ stderr ของการรันบรรทัดสถานะครั้งแรกในเซสชันนั้น
บันทึกการดีบั๊กแจ้งว่า Status line command skipped: workspace trust not accepted บรรทัดสถานะจะรันคำสั่งเชลล์ ดังนั้นจึงอยู่ภายใต้การควบคุมความปลอดภัยของ workspace เดียวกันกับ hooks จนกว่าคุณจะยอมรับกล่องโต้ตอบความเชื่อถือ (trust dialog) สำหรับไดเรกทอรีนั้น คำสั่งดังกล่าวจะไม่ทำงาน กรณีนี้พบได้บ่อยบน VPS ซึ่งทุกการ clone ใหม่จะเป็นไดเรกทอรีที่ Claude Code ยังไม่เคยรู้จัก ให้รีสตาร์ท Claude Code ในไดเรกทอรีนั้นแล้วกดยอมรับกล่องโต้ตอบ
ทุกอย่างว่างเปล่าและมีการตั้งค่า disableAllHooks ไว้ การตั้งค่า "disableAllHooks": true ใน settings.json จะปิดการทำงานของบรรทัดสถานะด้วยเช่นกัน เนื่องจากเป็นกลไกการรันเชลล์เดียวกัน ให้ลบออกหรือตั้งค่าเป็น false
แถวแสดงผลเป็น null ตัวเลือก jq เข้าถึงคีย์ที่ไม่มีอยู่หรือเป็นค่า null และ jq -r จะแสดงค่า null เป็นอักขระสี่ตัวคือ null ให้เพิ่ม // empty สำหรับข้อความและ // 0 สำหรับตัวเลข
แถวว่างเปล่าทันทีหลังจากที่คุณแก้ไขสคริปต์ คำสั่งที่จบการทำงานด้วยสถานะที่ไม่ใช่ศูนย์ (non-zero) หรือไม่แสดงผลลัพธ์ใดๆ จะทำให้แถวนั้นว่างเปล่า สาเหตุที่พบบ่อยคือบรรทัดสุดท้ายเป็นคำสั่งอย่าง [ -n "$BRANCH" ] && LINE="..." ซึ่งจะส่งคืนค่า exit code เป็น 1 เมื่อ branch ว่างเปล่าและส่งผลต่อ exit code ของสคริปต์ทั้งหมด ให้คงคำสั่ง printf ไว้เป็นบรรทัดสุดท้าย หรือเพิ่ม exit 0
รหัส Escape แสดงเป็นข้อความตัวอักษร เช่น \e]8;; บนแถบสถานะ ให้ใช้ printf '%b' แทน echo -e การใช้ลิงก์ OSC 8 ที่คลิกได้จำเป็นต้องใช้เทอร์มินัลที่รองรับ และ tmux หรือ SSH อาจตัดลำดับรหัสเหล่านี้ออก ดังนั้นการใช้สีแบบปกติจึงเป็นทางเลือกที่ปลอดภัยกว่าเมื่อใช้งานบนเครื่องระยะไกล
ด้านขวาของแถวถูกตัดออก การแจ้งเตือนของระบบและตัวนับโทเค็นในโหมด verbose จะใช้พื้นที่แถวนั้นร่วมกันจากด้านขวา หากเทอร์มินัลแคบเกินไปจะทำให้ข้อมูลส่วนที่ซ้อนทับกันหายไป ควรทำให้ผลลัพธ์สั้นกระชับ สำหรับการตรวจสอบการใช้งานจริงแทนที่จะดูเพียงตัวเลขบนแถบสถานะ โปรดดู วิธีการนับโทเค็นของ Claude Code
FAQ
การตั้งค่า statusline ของ Claude Code อยู่ที่ไหน
อยู่ใน settings.json โดยเป็นบล็อก statusLine ที่กำหนด type เป็น "command" และกำหนด command เป็นพาธของสคริปต์หรือคำสั่งเชลล์ การตั้งค่าของผู้ใช้จะอยู่ที่ ~/.claude/settings.json ซึ่งจะมีผลกับทุกโปรเจกต์บนเครื่องนั้น ส่วนการตั้งค่าของโปรเจกต์จะอยู่ที่ .claude/settings.json ภายใน repository และจะมีผลเหนือกว่าสำหรับไดเรกทอรีนั้น การตั้งค่าจะโหลดใหม่โดยอัตโนมัติ แต่การเปลี่ยนแปลงจะแสดงผลเมื่อมีการทริกเกอร์อัปเดตครั้งถัดไป เช่น เมื่อคุณส่งข้อความครั้งต่อไป
ทำไม statusline ของ Claude Code ถึงว่างเปล่า
สาเหตุส่วนใหญ่เกิดจาก 4 กรณีนี้: สคริปต์ขาดสิทธิ์ execute ทำให้เชลล์ส่งค่า Permission denied กลับมาและไม่มีข้อมูลส่งไปยัง stdout, ยังไม่ได้กดยอมรับกล่องโต้ตอบความเชื่อถือของ workspace ทำให้ claude --debug บันทึก log เป็น Status line command skipped: workspace trust not accepted, disableAllHooks ถูกตั้งค่าเป็น true ซึ่งจะปิดการใช้งาน statusline ภายใต้เงื่อนไขเดียวกัน หรือสคริปต์จบการทำงานด้วยสถานะที่ไม่ใช่ศูนย์ ทำให้แถบแสดงผลว่างเปล่า ให้ทดสอบด้วยตนเองก่อน: echo '{}' | ~/.claude/statusline.sh ต้องแสดงผลลัพธ์ออกมา
JSON ของ statusline รวมข้อมูล git branch หรือไม่
ไม่รวม JSON จะเก็บสถานะของเซสชัน เช่น โมเดล, ไดเรกทอรีของ workspace, ตัวเลข context window และค่าใช้จ่าย ไม่มีข้อมูลใดที่รายงานสถานะ git การแสดง branch บนแถบสถานะของคุณมาจากสคริปต์ที่คุณเขียนขึ้นเองเพื่อเรียกใช้ git branch --show-current ให้ส่งค่าไดเรกทอรีจาก JSON ด้วย git -C "$DIR" เพื่อให้ branch ตรงกับไดเรกทอรีที่แถบสถานะกำลังแสดงอยู่เสมอ
statusline ทำให้เปลือง token หรือทำให้เซสชันช้าลงหรือไม่
ไม่เปลือง token เพราะสคริปต์ทำงานในเครื่องและผลลัพธ์จะไม่ถูกส่งไปยังโมเดล ส่วนความเร็วขึ้นอยู่กับการจัดการของคุณ คำสั่งจะทำงานทุกครั้งที่มีข้อความจากผู้ช่วยโดยมีดีเลย์ 300 ms และ Claude Code จะยกเลิกการทำงานที่ค้างอยู่เมื่อมีการอัปเดตใหม่เข้ามา ดังนั้นสคริปต์ที่ใช้เวลาทำงานนานถึง 1 วินาทีจะแสดงข้อความที่ล้าสมัย หลีกเลี่ยงการใช้ git status ใน repository ขนาดใหญ่ และให้แคชข้อมูลที่ทำงานช้าไว้ในไฟล์โดยใช้ session_id เป็นคีย์
ฉันจะแสดง statusline ที่แตกต่างกันในแต่ละเซิร์ฟเวอร์ได้อย่างไร
ใช้สคริปต์ชุดเดียวและให้สคริปต์อ่านค่าจากเครื่องนั้นๆ สคริปต์ด้านบนจะแสดง $HOSTNAME โดยมี hostname -s เป็นค่าสำรอง ดังนั้นไฟล์เดียวกันที่คัดลอกไปยังทุกเครื่องจะระบุชื่อแต่ละเครื่องได้อย่างถูกต้อง และเทคนิคการใช้ checksum เพื่อกำหนดสีจะทำให้แต่ละ hostname มีสีเป็นของตัวเอง หากเซิร์ฟเวอร์ใดต้องการรูปแบบที่ต่างออกไป ให้ใส่บล็อก statusLine ไว้ในการตั้งค่าโปรเจกต์ของ repository ที่คุณใช้งานบนเครื่องนั้น เนื่องจากค่าการตั้งค่าโปรเจกต์จะแทนที่การตั้งค่าของผู้ใช้สำหรับไดเรกทอรีนั้นๆ