jvinhit//lab

Search posts

Type to search across journal entries.

navigate open esc close

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

  1. Chạy dev server hoặc một process dài, tìm PID bằng pgrep -fl.
  2. Tìm process nào đang giữ port dev của bạn bằng lsof -i :PORT.
  3. Dùng curl hoặc nc kiểm tra port có mở không.
  4. Dùng command -v kiểm tra node, 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.