跳至主要内容

Linux 服務管理進化論:systemctl 與 service 指令的差異與選用指南

· 閱讀時間約 7 分鐘
AIMDX 小編

在 Linux 系統管理中,服務(Service)的啟動、停止與狀態監控是日常維運的基本功。隨著 Linux 發行版的演進,管理服務的方式也歷經了重大的架構轉變:從早期基於 SysVinitservice 指令,過渡到現今主流的 systemd 及其配套工具 systemctl

理解這兩套工具的差異,不僅是系統管理員的必備知識,也有助於在面對不同年代的伺服器環境時,做出正確的判斷與因應。

systemctl 與 service 的演進示意圖

背景:兩種啟動系統的歷史脈絡

SysVinit 與 service 指令

早期的 Linux 系統(如 Debian 6、CentOS 5 等)採用 SysVinit(System V init)作為第一支啟動的行程(PID 1)。在這個架構中,服務管理是透過存放在 /etc/init.d/ 目錄下的 Shell Script 來實現的,而 service 指令則是這些 Script 的統一呼叫介面。

# 傳統 service 指令語法
service <服務名稱> <動作>

由於 /etc/init.d/ 內的每個檔案本質上都是 Shell Script,其功能、輸出格式與錯誤處理方式完全依賴各個撰寫者的實作,缺乏一致的標準。

systemd 與 systemctl 指令

約從 2011 年起,systemd 開始逐步取代 SysVinit,成為 Fedora、Ubuntu(15.04 後)、Debian(8 後)、CentOS/RHEL(7 後)等主流發行版的標準初始化系統。

systemctl 是 systemd 的主要管理指令,負責控制系統服務(Unit)、掛載點、Socket、Timer 等各種 systemd 資源。

# systemctl 指令語法
systemctl <動作> <服務名稱>

語法對照:常見操作比較

以下以 nginx 服務為例,對照兩種指令的常用操作:

操作service 指令(舊式)systemctl 指令(新式)
啟動服務service nginx startsystemctl start nginx
停止服務service nginx stopsystemctl stop nginx
重新啟動service nginx restartsystemctl restart nginx
重新載入設定service nginx reloadsystemctl reload nginx
查詢服務狀態service nginx statussystemctl status nginx
設定開機自啟chkconfig nginx onsystemctl enable nginx
取消開機自啟chkconfig nginx offsystemctl disable nginx
查詢是否開機自啟chkconfig --list nginxsystemctl is-enabled nginx

注意:在 SysVinit 架構下,「啟動服務」與「設定開機自啟」是兩個分離的工具(service + chkconfig),而 systemctl 則將兩者整合在同一套工具中管理。

核心架構差異

1. 底層實作機制

service 指令本質上是呼叫 /etc/init.d/<服務名稱> 的 Shell Script,腳本的邏輯、成功與否的判斷標準,完全由撰寫者自行決定。

systemctl 則依賴 Unit 檔案.service 格式),這些設定檔存放在 /lib/systemd/system//etc/systemd/system/ 目錄下,採用統一的 INI 格式,由 systemd 統一解析與執行。

# 典型的 systemd Unit 檔案結構(/lib/systemd/system/nginx.service)
[Unit]
Description=A high performance web server and a reverse proxy server
After=network.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t -q -g 'daemon on; master_process on;'
ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;'
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID

[Install]
WantedBy=multi-user.target

2. 平行啟動能力

SysVinit 採用序列式啟動,依照 /etc/rc*.d/ 中的符號連結數字依序執行,服務之間只能排隊等候。

systemd 則支援平行啟動(Parallel Startup),透過分析服務間的相依關係(After=, Requires=, Wants= 等指令),在相依關係允許的前提下同時啟動多個服務,大幅縮短系統開機時間。

3. 行程管理與追蹤

service 指令在執行完 Script 後便告結束,事後無從得知服務行程的狀態,也無法管理由服務衍生的子行程。

systemd 透過 cgroup(Control Groups) 機制,將服務的所有相關行程統一納管。即使服務衍生了子行程,systemd 也能完整追蹤,並在服務停止時確保所有子行程一併終止,杜絕殭屍行程(Zombie Process)的產生。

4. 日誌整合

使用 service 管理的傳統服務,日誌通常散落在 /var/log/ 目錄下的各個自訂檔案,格式不統一。

systemd 內建 journald 日誌系統,所有由 systemd 管理的服務輸出(stdout/stderr)都會自動匯入結構化的日誌資料庫,可透過統一的 journalctl 指令查詢:

# 查詢 nginx 服務的即時日誌
journalctl -u nginx -f

# 查詢最近 100 行日誌
journalctl -u nginx -n 100

# 查詢特定時間區間的日誌
journalctl -u nginx --since "2026-04-01" --until "2026-04-16"

優劣比較

service(SysVinit)的優點

  • 廣泛相容性:在非常舊的發行版或嵌入式系統中仍是唯一的選擇。
  • 結構簡單:Init Script 就是純 Shell Script,對熟悉 Bash 的系統管理員而言易於理解與修改。
  • 低依賴性:不依賴特定的 init 系統框架,可移植性較高。

service(SysVinit)的缺點

  • 序列啟動:服務必須依序啟動,開機時間較長。
  • 缺乏行程追蹤:無法確保服務停止時子行程也一併終止。
  • 日誌管理分散:各服務日誌格式不一,難以統一查詢。
  • 功能實作不一致:各個 Init Script 的行為完全取決於撰寫品質,缺乏規範。

systemctl(systemd)的優點

  • 平行啟動:大幅縮短系統開機時間。
  • 統一的 Unit 格式:服務設定標準化,可讀性與可維護性高。
  • 完善的行程管理:透過 cgroup 追蹤並控制所有衍生行程。
  • 整合式日誌系統:透過 journald 提供結構化、可查詢的集中日誌。
  • 豐富的依賴管理:可精確宣告服務的相依關係與啟動順序。
  • 自動重啟機制:可透過 Restart=on-failure 等設定實現服務崩潰後的自動恢復。

systemctl(systemd)的缺點

  • 學習曲線較陡:Unit 檔案語法與 systemd 的整體概念需要一定的學習時間。
  • 設計過於龐大:部分開發者批評 systemd 違反「Unix 哲學」的單一職責原則,承擔了過多的系統功能(包含日誌、網路、掛載等)。
  • 舊系統不適用:在 systemd 普及前的老舊系統或容器環境中可能無法使用。

相容層:現代系統中的 service 指令

值得注意的是,在已導入 systemd 的現代 Linux 發行版中,service 指令並未消失,而是作為一個 相容性包裝層(Compatibility Shim) 繼續存在。

執行 service nginx start 時,系統實際上會在內部自動轉呼叫 systemctl start nginx,以提供向後相容的指令介面。這意味著在現代系統上,兩者的執行結果幾乎相同,但 service 所提供的輸出資訊相對有限。

# 在 Ubuntu 22.04 上執行 service,其實內部呼叫了 systemctl
$ service nginx start
# 等同於
$ systemctl start nginx

選用建議

使用情境建議工具
現代 Linux 發行版(Ubuntu 16.04+, CentOS 7+, Debian 8+)systemctl
舊版系統(Ubuntu 14.04-, CentOS 6-, Debian 7-)service
撰寫需跨版本相容的腳本偵測後條件式選用
需查詢詳細服務日誌systemctl status + journalctl
嵌入式 Linux 或精簡環境service(視實際 init 系統而定)

以下為在 Shell Script 中偵測 init 系統並選用對應指令的範例:

#!/bin/bash
SERVICE_NAME="nginx"

if command -v systemctl &>/dev/null && systemctl list-units &>/dev/null; then
echo "使用 systemctl 管理服務"
systemctl restart "$SERVICE_NAME"
else
echo "使用 service 管理服務(SysVinit 環境)"
service "$SERVICE_NAME" restart
fi

總結

servicesystemctl 代表了 Linux 服務管理的兩個世代。前者以簡單的 Shell Script 為基礎,適用於舊有或精簡環境;後者則透過 systemd 的統一框架,提供了平行啟動、行程追蹤、結構化日誌等現代化管理能力。

在絕大多數的現代伺服器環境中,systemctl 已是服務管理的事實標準。熟練掌握其語法與 Unit 檔案的設定,是在當代 Linux 環境中高效維運的基礎技能。