Headless Mode
Module 11.1: Headless Mode
Phần tiêu đề “Module 11.1: Headless Mode”Thời gian học: ~30 phút
Yêu cầu trước: Phase 10 (Team Collaboration)
Kết quả: Sau module này, bạn sẽ hiểu headless mode căn bản, biết cách script Claude Code, và sẵn sàng cho automation nâng cao.
1. WHY — Tại Sao Điều Này Quan Trọng
Phần tiêu đề “1. WHY — Tại Sao Điều Này Quan Trọng”Bạn muốn chạy Claude Code như một phần của script. Có thể là tự động generate test cho toàn bộ file trong thư mục. Có thể là code review tự động cho mọi PR. Có thể là batch process documentation. Nhưng Claude Code là interactive — nó chờ input của bạn, hiển thị spinner, yêu cầu approval.
Headless mode giải quyết vấn đề này: Claude thực thi, xuất kết quả, trả quyền điều khiển lại cho script của bạn. Không cần tương tác. Điều này mở ra automation: cron job, CI/CD pipeline, batch processing, và nhiều hơn nữa.
2. CONCEPT — Ý Tưởng Cốt Lõi
Phần tiêu đề “2. CONCEPT — Ý Tưởng Cốt Lõi”Interactive vs Headless
Phần tiêu đề “Interactive vs Headless”| Khía cạnh | Interactive | Headless |
|---|---|---|
| Khởi chạy | claude | claude -p "prompt" |
| Đầu vào | Hội thoại | Một prompt duy nhất |
| Đầu ra | Có format, spinner | Raw stdout |
| Approval | Bắt buộc | Bỏ qua hoặc tự động |
| Use case | Development | Automation |
Flag -p
Phần tiêu đề “Flag -p”Flag -p (print) là chìa khóa của headless mode:
claude -p "Prompt của bạn ở đây"- Thực thi prompt
- Xuất kết quả ra stdout
- Trả về shell khi hoàn tất
- Exit code cho biết thành công/thất bại
Capturing Output
Phần tiêu đề “Capturing Output”# Lưu vào biếnresult=$(claude -p "Giải thích function này")
# Ghi vào fileclaude -p "Generate README" > README.md
# Pipe sang command khácclaude -p "List issues trong code" | grep "ERROR"Phương Thức Input
Phần tiêu đề “Phương Thức Input”# Prompt trực tiếpclaude -p "Giải thích recursion"
# Với context từ fileclaude -p "Review code này: $(cat file.js)"
# Pipe từ stdin ⚠️ Cần verify hỗ trợcat file.js | claude -p "Review code này"Exit Code
Phần tiêu đề “Exit Code”0: Thành công- Non-zero: Lỗi (check stderr)
- Dùng trong script:
if claude -p "..."; then ... fi
3. DEMO — Từng Bước
Phần tiêu đề “3. DEMO — Từng Bước”Scenario: Tự động hóa việc tạo documentation bằng headless Claude Code.
Bước 1: Thực Thi Headless Cơ Bản
Phần tiêu đề “Bước 1: Thực Thi Headless Cơ Bản”claude -p "2 + 2 bằng bao nhiêu?"Output:
4Kiểm tra exit code:
echo $?Output:
0Bước 2: Capture Vào Biến
Phần tiêu đề “Bước 2: Capture Vào Biến”explanation=$(claude -p "Giải thích async/await trong một đoạn văn")echo "$explanation"Output:
Async/await là tính năng JavaScript giúp code bất đồng bộdễ viết và dễ đọc hơn bằng cách cho phép bạn viết các thao tácbất đồng bộ theo cú pháp trông như đồng bộ...Bước 3: Generate File Từ Output
Phần tiêu đề “Bước 3: Generate File Từ Output”claude -p "Generate README.md cho một TypeScript utility library" > README.mdhead -5 README.mdOutput:
# TypeScript Utility Library
Một tập hợp các tiện ích TypeScript hữu ích cho các tác vụ phổ biến.
## Cài ĐặtBước 4: Xử Lý Nhiều File
Phần tiêu đề “Bước 4: Xử Lý Nhiều File”#!/bin/bashfor file in src/*.ts; do echo "Đang document $file..." doc=$(claude -p "Generate JSDoc comment cho: $(cat "$file")") echo "$doc" > "docs/$(basename "$file" .ts).md"done
echo "Documentation hoàn tất!"Chạy script:
chmod +x generate-docs.sh./generate-docs.shOutput:
Đang document src/utils.ts...Đang document src/helpers.ts...Đang document src/api.ts...Documentation hoàn tất!Bước 5: Logic Điều Kiện Dựa Trên Output
Phần tiêu đề “Bước 5: Logic Điều Kiện Dựa Trên Output”#!/bin/bashresult=$(claude -p "Review code này để tìm lỗi bảo mật.Output 'SAFE' nếu không có vấn đề, hoặc 'UNSAFE: [lý do]' nếu có vấn đề.Code: $(cat "$1")")
if [[ "$result" == SAFE* ]]; then echo "✅ $1 passed security check" exit 0else echo "❌ $1 failed: $result" exit 1fiChạy script:
./check-security.sh src/app.jsOutput (trường hợp an toàn):
✅ src/app.js passed security checkOutput (trường hợp có vấn đề):
❌ src/app.js failed: UNSAFE: SQL injection vulnerability detectedBước 6: Xử Lý Lỗi
Phần tiêu đề “Bước 6: Xử Lý Lỗi”if ! output=$(claude -p "Generate test cho $(cat file.js)" 2>&1); then echo "Lỗi: $output" exit 1fiecho "$output" > tests.js4. PRACTICE — Thực Hành
Phần tiêu đề “4. PRACTICE — Thực Hành”Bài Tập 1: Lệnh Headless Đầu Tiên
Phần tiêu đề “Bài Tập 1: Lệnh Headless Đầu Tiên”Mục tiêu: Thực thi lệnh Claude headless đầu tiên của bạn.
Hướng dẫn:
- Chạy:
claude -p "Nói xin chào" - Capture vào biến:
greeting=$(claude -p "Nói xin chào") - Echo biến:
echo "$greeting" - Kiểm tra exit code:
echo $?
💡 Gợi Ý
Output sẽ là một lời chào đơn giản. Exit code 0 nghĩa là thành công.
✅ Giải Pháp
claude -p "Nói xin chào"# Output: Xin chào!
greeting=$(claude -p "Nói xin chào")echo "$greeting"# Output: Xin chào!
echo $?# Output: 0 (thành công)Bài Tập 2: Generate File
Phần tiêu đề “Bài Tập 2: Generate File”Mục tiêu: Generate code vào file.
Hướng dẫn:
- Generate function:
claude -p "Viết JavaScript function để viết hoa chữ cái đầu" > capitalize.js - Verify:
cat capitalize.js - Chạy:
node -e "$(cat capitalize.js); console.log(capitalize('hello'))"
💡 Gợi Ý
Dùng redirect > để ghi output vào file. Dùng $(cat file) để đọc nội dung file làm input.
✅ Giải Pháp
claude -p "Viết JavaScript function tên capitalize nhận string và return với chữ cái đầu viết hoa" > capitalize.jscat capitalize.jsnode -e "$(cat capitalize.js); console.log(capitalize('hello'))"# Output: HelloBài Tập 3: Batch Processing Script
Phần tiêu đề “Bài Tập 3: Batch Processing Script”Mục tiêu: Xử lý nhiều file bằng script.
Hướng dẫn:
- Tạo 3 file code nhỏ trong test directory
- Viết bash script loop qua các file
- Với mỗi file, generate mô tả một dòng
- Output tất cả mô tả vào summary.txt
💡 Gợi Ý
Dùng for file in directory/*.js để loop. Dùng >> để append vào summary file thay vì overwrite.
✅ Giải Pháp
# Tạo test filemkdir -p test-batchecho "function add(a, b) { return a + b; }" > test-batch/math.jsecho "const API_URL = 'https://api.example.com';" > test-batch/config.jsecho "class User { constructor(name) { this.name = name; } }" > test-batch/user.js
# Batch processing script (lưu thành batch-describe.sh)#!/bin/bashfor file in test-batch/*.js; do name=$(basename "$file") desc=$(claude -p "Mô tả trong một dòng: $(cat "$file")") echo "$name: $desc" >> test-batch/summary.txtdone
# Chạy và verifychmod +x batch-describe.sh./batch-describe.shcat test-batch/summary.txt5. CHEAT SHEET
Phần tiêu đề “5. CHEAT SHEET”Headless Cơ Bản
Phần tiêu đề “Headless Cơ Bản”claude -p "prompt" # Thực thi và outputresult=$(claude -p "prompt") # Capture vào biếnclaude -p "prompt" > file.txt # Output vào fileclaude -p "prompt" | grep "pattern" # Pipe sang commandVới File Input
Phần tiêu đề “Với File Input”claude -p "Review: $(cat file.js)" # Inline nội dung fileTrong Script
Phần tiêu đề “Trong Script”# Xử lý lỗiif ! result=$(claude -p "..."); then echo "Failed" exit 1fi
# Loop processingfor f in *.js; do claude -p "Document: $(cat "$f")" > "${f%.js}.md"doneExit Code
Phần tiêu đề “Exit Code”| Code | Ý Nghĩa |
|---|---|
| 0 | Thành công |
| Non-zero | Lỗi |
Flag Quan Trọng ⚠️ Cần verify khả dụng
Phần tiêu đề “Flag Quan Trọng ⚠️ Cần verify khả dụng”| Flag | Mục Đích |
|---|---|
-p "prompt" | Thực thi headless |
--help | Hiển thị các tùy chọn có sẵn |
6. PITFALLS — Lỗi Thường Gặp
Phần tiêu đề “6. PITFALLS — Lỗi Thường Gặp”| ❌ Sai Lầm | ✅ Cách Đúng |
|---|---|
| Mong đợi tính năng interactive | Headless là one-shot. Không có conversation. |
| Prompt dài trực tiếp trong command | Dùng biến hoặc file cho prompt dài |
| Bỏ qua exit code | Luôn check exit code trong script |
| Không escape ký tự đặc biệt | Quote biến: "$(cat file)" |
| Giả định hành vi giống interactive | Test headless riêng. Output format khác. |
| Không xử lý lỗi | Capture stderr, check exit code |
| Overload với file khổng lồ | Context limit vẫn áp dụng. Chia nhỏ file lớn. |
7. REAL CASE — Câu Chuyện Thực Tế
Phần tiêu đề “7. REAL CASE — Câu Chuyện Thực Tế”Scenario: Một startup Việt Nam cần tạo API documentation cho 50+ endpoint. Quy trình thủ công mất 2 ngày cho mỗi lần update documentation.
Giải pháp với headless mode:
#!/bin/bashfor endpoint in src/routes/*.ts; do name=$(basename "$endpoint" .ts) echo "Đang document $name..."
claude -p "Generate OpenAPI documentation cho endpoint này:$(cat "$endpoint")
Output ở định dạng YAML." > "docs/api/$name.yaml"done
# Gộp tất cả YAML fileclaude -p "Gộp các OpenAPI spec này thành một:$(cat docs/api/*.yaml)" > docs/openapi.yaml
echo "API documentation đã được tạo!"Kết quả:
- 2 ngày thủ công → 15 phút tự động
- Chạy hàng đêm qua cron job
- Documentation luôn up-to-date
- Chỉ cần human review khi cần thiết
Quote: “Headless mode đã biến Claude từ chat buddy thành documentation factory.”
Phase Tiếp Theo: Module 11.2: SDK Integration →