Linux 系統管理中,「殺掉進程」是基本功。從基本的 kill 到進階的 pkill、killall、圖形化 xkill、互動式 top/htop,本文匯總所有常用姿勢,並解析訊號機制,讓您精準、優雅地管理進程。
# 完整格式列出所有進程
ps -ef
# BSD 風格,顯示 CPU/記憶體佔用
ps -aux
# 結合 grep 過濾特定進程
ps -ef | grep firefox
ps -aux | grep nginx
輸出關鍵欄位:UID (用戶)、PID (進程 ID)、PPID (父進程)、C (CPU%), STIME (啟動時間)、TTY (終端)、TIME (CPU 時間)、CMD (命令)。
# 語法:kill [-s 信號] PID
# 預設發送 SIGTERM (15) 訊號,請求進程優雅退出 (釋放資源、存檔、關閉連線)
kill 1827
# 強制終結:發送 SIGKILL (9) 訊號,核心強制回收資源,進程無法攔截/拒絕
kill -9 1827
kill -s 9 1827
kill -s KILL 1827
# 按進程名稱殺死所有匹配進程
pkill firefox
# 指定訊號
pkill -9 firefox
pkill -KILL firefox
# 按用戶殺死該用戶所有進程
pkill -u username
# 按終端機殺死該終端的所有進程
pkill -t pts/0
# 完整命令列匹配 (預設只匹配進程名稱前 15 字元)
pkill -f "java -jar myapp.jar"
# 僅列出匹配 PID 不殺進程 (搭配 pgrep)
pgrep firefox
pgrep -f "java -jar"
# 必須提供完整進程名稱 (不支援模糊/正則)
killall firefox
killall -9 nginx
# 按用戶
killall -u username
# 交互式確認
killall -i firefox
pkill vs killall: pkill 支援模式匹配、更靈活;killall 需精確名稱、在某些 Unix (Solaris/AIX) 行為不同 (可能殺掉所有用戶進程),Linux 下較安全但功能較少。**推薦優先使用 pkill。**
# 執行後滑鼠游標變為 X/骷髏頭,點擊任意視窗即殺死該視窗對應進程
xkill
SIGTERM 給視窗擁有進程。top
進入介面後熱鍵:
apt/yum/dnf install htop)top 作為日常互動式管理工具。| 信號編號 | 名稱 | 用途 | 可被捕獲/忽略 | 典型場景 |
|---|---|---|---|---|
| 1 | SIGHUP | 掛起/終端斷開,常用於通知守護進程重讀配置 | 是 | nginx -s reload, systemctl reload |
| 2 | SIGINT | 中斷 (Ctrl+C) | 是 | 前景程式正常退出 |
| 3 | SIGQUIT | 退出並產生核心傾印 | 是 | 除錯需核心檔案 |
| 9 | SIGKILL | **強制殺死,核心直接回收資源** | 否 (不可捕獲/忽略/阻塞) | **頑固卡死進程、殭屍進程清理、最後手段** |
| 15 | SIGTERM | **標準終止請求,預設信號** | 是 | **正常關閉服務、應用,給機會優雅退出** |
| 18 | SIGCONT | 繼續執行 (配合 SIGSTOP) | 否 | 作業控制 |
| 19 | SIGSTOP | 暫停執行 (不可捕獲) | 否 | 凍結進程 |
| 20 | SIGTSTP | 終端暫停 (Ctrl+Z) | 是 | 作業控制 |
黃金法則: **先試 SIGTERM (15/預設),等待 5-10 秒,無反應再用 SIGKILL (9)**。濫用 SIGKILL 會導致資料遺失、檔案損壞、鎖檔案未釋放、子進程變孤兒/殭屍。
ps 顯示 Z 狀態)wait() 回收。無法直接 kill。解決:殺死父進程 (讓 init 繼承回收) 或重啟服務/系統。kill -9 也殺不掉。解決:恢復底層 I/O (掛載點/網路/硬碟)、重啟系統。sudo 或 root 身分殺系統/其他用戶進程。#!/bin/bash
# graceful_stop.sh <進程名稱/模式>
PATTERN="$1"
if [ -z "$PATTERN" ]; then echo "Usage: $0 "; exit 1; fi
PIDS=$(pgrep -f "$PATTERN")
if [ -z "$PIDS" ]; then echo "No matching processes."; exit 0; fi
echo "Found PIDs: $PIDS"
echo "Sending SIGTERM..."
pkill -f "$PATTERN"
sleep 5
REMAINING=$(pgrep -f "$PATTERN")
if [ -n "$REMAINING" ]; then
echo "Still alive: $REMAINING. Sending SIGKILL..."
pkill -9 -f "$PATTERN"
sleep 2
FINAL=$(pgrep -f "$PATTERN")
[ -z "$FINAL" ] && echo "All stopped." || echo "FAILED: $FINAL still running."
else
echo "All stopped gracefully."
fi
熟練掌握 ps | grep → pkill/kill 流程,善用 htop 視覺化操作,理解訊號語義,**優雅終結**而非暴力殺戮,是 Linux 系統管理員的專業素養。