Command Line cho Developer · Part 7 - Processes, Ports & System Debugging
Debug máy dev bằng CLI: ps, pgrep, kill, lsof, ss/netstat, nc, top/htop, env, PATH, command -v, df/du và recipe xử lý port bị chiếm.
Đây là Phần 7. Có những lỗi không nằm trong code:
- dev server không start vì port bị chiếm;
- command không chạy vì binary không nằm trong
PATH; - app treo vì process cũ vẫn sống;
- máy hết disk;
- request local fail vì service chưa listen.
Command line giúp bạn nhìn vào hệ thống đang chạy.
Process là gì?
Mỗi chương trình đang chạy là một process, có PID.
ps
ps aux | head
Tìm process theo tên:
pgrep -fl node
pgrep -fl vite
pgrep -fl astro
-f search cả command line, -l in tên.
Xem cây process:
ps -ef | rg "node|vite|astro"
Trên macOS/BSD, ps aux quen hơn; trên Linux, ps -ef cũng phổ biến.
Dừng process với kill
kill 12345
Mặc định kill gửi SIGTERM, yêu cầu process tự dừng.
Nếu process không chịu dừng:
kill -9 12345
-9 là SIGKILL, hệ điều hành kết thúc ngay. Dùng như phương án cuối vì process không có cơ hội cleanup.
Tìm và kill theo tên:
pkill -f "vite"
Cẩn thận với pkill -f: pattern rộng có thể kill nhiều process hơn bạn muốn. Chạy pgrep -fl "pattern" trước.
Port bị chiếm
Lỗi quen thuộc:
Error: listen EADDRINUSE: address already in use :::3000
Trên macOS/Linux, dùng lsof:
lsof -i :3000
Output có PID. Dừng process:
kill 12345
Một dòng:
lsof -ti :3000 | xargs kill
Nếu danh sách rỗng, xargs kill có thể gây lỗi tùy hệ. An toàn hơn khi viết script thì kiểm tra trước.
Trên Linux, ss rất hữu ích:
ss -ltnp
ss -ltnp | rg ':3000'
netstat cũ hơn nhưng vẫn gặp nhiều:
netstat -an | rg '3000'
Kiểm tra service có listen không
Dùng curl cho HTTP:
curl -i http://localhost:3000
Dùng nc cho TCP port chung:
nc -vz localhost 3000
nc -vz localhost 5432
Nếu nc báo connected, port mở. Nếu refused/timed out, service chưa chạy, sai host/port, firewall, hoặc container chưa expose port.
Tài nguyên máy: CPU, memory, disk
Xem process realtime:
top
htop
htop dễ đọc hơn nhưng thường cần cài thêm.
Disk:
df -h
du -h -d 1 . | sort -h | tail
Memory:
free -h # Linux
vm_stat # macOS
Nếu Docker build hoặc package install fail kỳ lạ, kiểm tra disk trước. Máy hết disk tạo ra lỗi rất vòng vèo.
PATH và binary resolution
Khi command not found:
echo "$PATH"
command -v node
command -v npm
command -v pnpm
type node
which node
Ưu tiên command -v trong script vì nó portable và đúng mục tiêu: command có chạy được không.
Ví dụ kiểm tra dependency:
if ! command -v jq >/dev/null 2>&1; then
echo "jq is required" >&2
exit 1
fi
PATH là danh sách thư mục shell sẽ tìm khi bạn gõ command. Nếu cài tool rồi vẫn “not found”, có thể PATH chưa chứa thư mục bin của tool đó.
Environment variables
In env:
env
printenv
printenv PATH
Chạy một command với env tạm:
NODE_ENV=production npm run build
DEBUG=1 npm test
Export cho phiên shell hiện tại:
export API_BASE_URL=http://localhost:3000
curl "$API_BASE_URL/health"
Khi debug lỗi “works on my machine”, so sánh env giữa máy bạn, CI, container và server.
Recipe xử lý port 3000 bị chiếm
lsof -i :3000
Nếu thấy process lạ:
kill <PID>
Nếu process là dev server cũ và không chịu dừng:
kill -9 <PID>
Kiểm tra lại:
lsof -i :3000
npm run dev
Nếu vẫn lỗi, có thể app listen port khác qua env:
env | rg 'PORT|HOST'
Bài tập
- Chạy dev server hoặc một process dài, tìm PID bằng
pgrep -fl. - Tìm process nào đang giữ port dev của bạn bằng
lsof -i :PORT. - Dùng
curlhoặcnckiểm tra port có mở không. - Dùng
command -vkiểm tranode,npm,git,jq.
Lời giải tham khảo
pgrep -fl node
lsof -i :3000
curl -i http://localhost:3000
nc -vz localhost 3000
command -v node npm git jqĐiều cốt lõi
Khi lỗi nằm ngoài code, nhìn vào process, port, PATH, env và disk. ps/pgrep, kill, lsof, ss, curl/nc, df/du, command -v là bộ đồ nghề nhỏ nhưng cứu rất nhiều giờ debug.