Linux 程序管理入門:ps、kill、背景執行完整解說
程序(Process)是什麼?
每當你執行一個程式(ls、vim、nginx),Linux 核心就會建立一個程序(Process)——這是程式正在執行的實例。程序有獨立的記憶體空間、資源和狀態。
| 名詞 | 說明 | 例子 |
|---|---|---|
| 程序(Process) | 正在執行中的程式實例 | 你開啟的每個 nginx worker 都是一個程序 |
| PID | 程序識別碼,每個程序有唯一的數字 ID | ps aux 輸出的第二欄 |
| PPID | 父程序 ID(啟動此程序的程序) | 你的 bash 是 sshd 的子程序 |
| 執行緒(Thread) | 同一程序內的平行執行單位,共用記憶體 | nginx 的多個 worker 執行緒 |
systemd(PID 1)
└── sshd(SSH 服務)
└── bash(你的登入 Shell)
└── vim(你正在編輯的編輯器)
└── ping(你執行的 ping)
查看程序:ps 與 top
ps aux — 靜態快照
$ ps aux | head -6
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 225384 9128 ? Ss 08:00 0:01 /sbin/init
www-data 1234 0.2 1.5 512000 31000 ? S 09:00 0:05 nginx: worker
alice 5678 0.0 0.1 12024 5200 pts/0 Ss 10:00 0:00 bash
alice 9999 0.0 0.0 12024 1024 pts/0 R+ 10:30 0:00 ps aux
各欄位說明:
- STAT:程序狀態 —
S=睡眠中,R=執行中,Z=殭屍,T=暫停,s=Session Leader - %CPU:CPU 使用百分比
- %MEM:實體記憶體使用百分比
- VSZ:虛擬記憶體大小(KB)
- RSS:實際使用的實體記憶體(KB)
常用的 ps 組合
$ ps aux | grep nginx # 找 nginx 的程序
$ ps aux --sort=-%mem | head -10 # 依記憶體排序
$ ps -u alice # 只看 alice 的程序
$ pstree # 以樹狀圖顯示程序階層
top — 即時動態監控
$ top
top 常用的互動快捷鍵:
| 按鍵 | 功能 |
|---|---|
| P | 依 CPU 使用率排序 |
| M | 依記憶體使用率排序 |
| 1 | 展開顯示各 CPU 核心 |
| k | 輸入 PID 來 kill 程序 |
| q | 退出 |
推薦安裝更好用的 htop:
$ sudo apt install htop && htop
訊號(Signal)與 kill
Linux 用訊號(Signal)來通知程序發生了某件事。kill 指令雖然名字叫「殺」,但它其實是「傳送訊號」的工具。
| 訊號 | 數字 | 意義 | 程序能捕捉? |
|---|---|---|---|
SIGTERM | 15 | 請求程序優雅地結束(預設) | 可以(可以做清理) |
SIGKILL | 9 | 強制立即終止(不可抵擋) | 不行 |
SIGHUP | 1 | 通知程序重新讀取設定(常用於 daemon) | 可以 |
SIGINT | 2 | Ctrl+C 觸發的中斷訊號 | 可以 |
kill 的正確使用順序
$ # 步驟 1:先找到 PID
pgrep -la nginx
1234 nginx: master process /usr/sbin/nginx
1235 nginx: worker process
$ # 步驟 2:先用 SIGTERM(優雅結束)
kill 1234
$ # 步驟 3:幾秒後若程序仍存在,再用 SIGKILL
kill -9 1234
不要習慣性地直接用
kill -9。SIGKILL 不讓程序做清理,可能造成資料損毀、鎖定檔案殘留。先試 kill(SIGTERM),只有在程序真的不回應時才用 kill -9。
前景(Foreground)與背景(Background)執行
啟動一個指令時,預設是在前景執行——它佔用終端機,你無法輸入其他指令。
在背景執行:加 &
$ wget -c https://example.com/large-file.iso &
[1] 12345
方括號是工作號碼,後面是 PID。現在終端機可以繼續使用。
暫停前景工作、放到背景
$ make -j8 # 執行中的前景工作
# 按 Ctrl+Z 暫停
$ bg %1 # 讓工作 1 在背景繼續執行
把背景工作帶回前景
$ jobs # 查看所有背景工作
[1]+ Running wget -c https://example.com/large-file.iso &
$ fg %1 # 將工作 1 帶回前景
nohup:讓程序在 SSH 斷線後繼續執行
當你關閉 SSH 連線,Shell 會傳送 SIGHUP 給所有子程序,導致它們結束。nohup 讓程序忽略這個訊號,在你離開後繼續執行。
$ nohup python3 long-task.py > task.log 2>&1 &
[1] 12345
格式說明:
nohup:讓程序忽略 SIGHUP> task.log:標準輸出寫到 task.log(不再是螢幕)2>&1:錯誤訊息也寫到同一個 task.log&:在背景執行
之後重新登入,用 ps aux | grep long-task 確認程序仍在執行。
更好的替代方案:使用 tmux 或 screen,可以在登出後重新連接並繼續操作。
systemctl:管理系統服務
nginx、MySQL、SSH 等服務通常是用 systemd 管理的。systemctl 是控制 systemd 的工具:
$ systemctl status nginx # 查看狀態(最常用)
$ sudo systemctl start nginx # 啟動
$ sudo systemctl stop nginx # 停止
$ sudo systemctl restart nginx # 重啟
$ sudo systemctl enable nginx # 設定開機自動啟動
$ sudo systemctl enable --now nginx # 啟用並立即啟動(一步完成)
程序問題排查
找出佔用高 CPU 的程序
$ ps aux --sort=-%cpu | head -10
找出某個 port 被哪個程序佔用
$ sudo ss -tlnp | grep :80
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=1234,fd=6))
找出「殭屍程序」(Zombie)
$ ps aux | grep ' Z '
殭屍程序(狀態 Z)是已經結束但父程序還沒回收的程序,通常無害但大量出現代表父程序有問題。