「關機」看似簡單,但 shutdown、halt、poweroff、reboot、systemctl、init 行為微妙不同,用錯可能導致資料遺失、服務未正確停止、檔案系統損壞。本文系統釐清各指令機制、參數、適用場景、systemd 與 SysVinit 差異、最佳實踐與自動化腳本範例。
| 指令 | 系統調用/機制 | 行為 | systemd 關聯 | 適用場景 |
|---|---|---|---|---|
| shutdown | 發送信號給 init (PID 1),切換 runlevel/target | 排程關機、通知所有用戶、禁止新登入、執行關機腳本 | systemctl poweroff / systemctl halt | 生產環境計畫性維護、多用戶系統 |
| halt | 調用 shutdown -h 或直接 reboot(RB_HALT_SYSTEM) | 殺進程、sync、停止核心、不切斷電源 (視參數/ACPI) | systemctl halt | 需進入韌體/BIOS、硬體診斷、單用戶模式 |
| poweroff | reboot(RB_POWER_OFF) (ACPI) | 同 halt 但切斷電源 | systemctl poweroff | 正常關機、虛擬機、實體機 |
| reboot | reboot(RB_AUTOBOOT) | 關機流程後重新開機 | systemctl reboot | 核心更新、硬體變更、系統卡死恢復 |
| systemctl poweroff/halt/reboot | systemd 管理器協調單元停止、依賴排序 | 正確停止所有服務、執行 ExecStop、同步檔案系統 | 原生 | systemd 系統首選 (現代 Linux 通用) |
| init 0/6 | SysVinit 切換 runlevel | 舊式 runlevel 機制 | 相容模式 | 舊版 RHEL 6、SysVinit 容器 |
shutdown [選項] [時間] [警告訊息]
選項:
-h, --halt 關機後停止核心 (不切電,等同 halt)
-P, --poweroff 關機後切斷電源 (預設行為,等同 poweroff)
-r, --reboot 重新開機
-k 只發送警告訊息,不真正關機 (演練用)
-c 取消已排程的關機
--no-wall 不發送廣播給所有終端機
時間格式:
now 立即 (別用 +0,某些版本解析不同)
+m m 分鐘後 (如 +10)
HH:MM 具體時間 (24小時制)
+0 立即 (同 now,但較明確)
# 立即關機切電 (生產首選)
shutdown -P now "系統維護,立即關機"
# 10 分鐘後重啟,通知用戶
shutdown -r +10 "10 分鐘後重啟套用核心更新,請儲存工作"
# 23:30 定時關機
shutdown -h 23:30 "夜間備份完成後關機"
# 取消排程
shutdown -c "取消關機,維護窗口延後"
# 只發警告不關機 (演練)
shutdown -k +5 "演練:5 分鐘後假裝關機"
# 關機切電
systemctl poweroff
# 關機不切電 (進入韌體)
systemctl halt
# 重啟
systemctl reboot
# 進入救援模式 (單用戶)
systemctl rescue
# 進入緊急模式 (最小掛載)
systemctl emergency
# 查看關機/重啟目標
systemctl list-units --target=shutdown.target
systemctl list-units --target=reboot.target
優勢:systemd 會依據單元依賴關係、順序正確停止服務 (執行 ExecStop、ExecStopPost)、同步檔案系統、處理加密磁碟關閉、取消網路儲存掛載,避免資料損壞。
# runlevel 0 = 關機 (halt),6 = 重啟
init 0
init 6
# telinit 同 init
telinit 0
telinit 6
# 直接呼叫關機腳本 (不推薦,繞過 init)
/etc/rc.d/rc.local stop # 不標準
| 參數 | halt | poweroff | reboot |
|---|---|---|---|
-n | 不 sync (危險!) | 不 sync | 不 sync |
-w | 只寫 wtmp 不關機 | 只寫 wtmp | 只寫 wtmp |
-f | 強制,不呼叫 shutdown (危險!) | 強制 | 強制 |
-i | 關閉網路介面再關機 | 關閉網路介面 | 關閉網路介面 |
-p | 關機時切電 (預設) | 切電 (預設) | - |
警告:-f、-n 繞過正常關機流程,極易造成檔案系統損壞、資料庫不一致、RAID 重建。絕不可在生產環境常態使用。
| 平台 | 推薦指令 | 說明 |
|---|---|---|
| VMware / VirtualBox / KVM (qemu-guest-agent) | systemctl poweroff | Agent 會協助同步、優雅關機 |
| AWS EC2 | shutdown -h now 或主控台 Stop | Stop = 關機保留 EBS,Terminate = 刪除 |
| GCP Compute Engine | systemctl poweroff 或 gcloud compute instances stop | 支援客體環境優雅關機 |
| Azure VM | systemctl poweroff 或入口網站停止 | 需安裝 Azure Linux Agent |
| Docker 容器 | docker stop CONTAINER (SIGTERM → 10s → SIGKILL) | 容器內用 trap 捕獲 SIGTERM 清理 |
#!/bin/bash
# /usr/local/bin/safe-shutdown.sh
set -euo pipefail
LOG="/var/log/safe-shutdown.log"
notify() { echo "[$(date -Iseconds)] $*" | tee -a "$LOG"; }
notify "開始安全關機流程"
# 1. 檢查關鍵服務狀態
for svc in postgresql mysql nginx docker; do
if systemctl is-active --quiet "$svc"; then
notify "停止服務: $svc"
systemctl stop "$svc"
fi
done
# 2. 同步檔案系統
notify "同步檔案系統..."
sync; sync; sync
# 3. 卸載網路/加密掛載 (可選)
# umount -a -t nfs,cifs,ecryptfs 2>/dev/null || true
# 4. 執行關機
notify "執行 systemctl poweroff"
systemctl poweroff
# /etc/cron.d/kernel-reboot
# 每天 03:00 檢查是否需重啟 (needs-restarting -r 來自 yum-utils/dnf-utils)
0 3 * * * root /usr/bin/needs-restarting -r || /usr/sbin/shutdown -r +5 "核心更新需重啟,5分鐘後自動重啟"
halt 會切電。事實:預設不切電,需 -p 或 ACPI 支援。reboot 等於 shutdown -r now。事實:reboot 在 runlevel 0/6 才直接重啟,否則呼叫 shutdown -r (systemd 下同)。kill -9 1 殺 init。後果:核心恐慌、立即重啟/停機,零清理。systemctl poweroff/reboot/halt。shutdown -P/+m/HH:MM "msg"。systemctl,前置檢查服務停止、同步、卸載。-f、-n、kill -9 1、直接斷電。正確的關機/重啟,是系統穩定、資料完整的最後一道防線。養成「先通知、再停止服務、後同步、最後 systemctl」的習慣,讓每一次重啟都安心無虞。