Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Linux rc.local 自啟動服務配置詳解與最佳實踐

編輯:Linux 教學

前言

/etc/rc.local(或 /etc/rc.d/rc.local)是 SysV init 時代留下的「使用者自訂啟動腳本」入口。雖然 systemd 已成為主流,但 rc.local 因其簡單直觀,仍被大量腳本、容器啟動指令、廠商專屬安裝程式依賴。本文解析 rc.local 在傳統啟動流程中的位置、systemd 兼容機制、常見坑點與現代替代方案。

一、傳統 SysV init 啟動流程中的 rc.local

  1. BIOS/UEFI → MBR/GRUB → Kernel + initramfs
  2. PID 1: /sbin/init 讀取 /etc/inittab
  3. 執行 /etc/rc.d/rc.sysinit(系統級初始化:網路、swap、fsck、hostname...)
  4. 依運行等級進入 /etc/rc.d/rcN.d/(N = 0-6)
  5. 執行 S* 開頭腳本啟動服務
  6. 最後執行 /etc/rc.d/rc.local(使用者自訂,S99local 或直接在 inittab 呼叫)
  7. 啟動 getty/login

rc.local 典型掛載方式(手動建立)


# 1. 建立檔案並賦予執行權限
touch /etc/rc.d/rc.local
chmod +x /etc/rc.d/rc.local

# 2. 在各運行等級建立 S99 連結(確保最後執行)
for i in {1..5}; do
  ln -sf /etc/rc.d/rc.local /etc/rc.d/rc${i}.d/S99rc.local
done
# rc0.d/rc6.d 通常不需啟動,可建 K99 關閉腳本

二、systemd 時代的 rc.local 兼容機制

systemd 提供 rc-local.service 兼容單元:


# /usr/lib/systemd/system/rc-local.service
[Unit]
Description=/etc/rc.d/rc.local Compatibility
After=network.target

[Service]
Type=forking
ExecStart=/etc/rc.d/rc.local start
TimeoutSec=0
RemainAfterExit=yes
GuessMainPID=no

[Install]
WantedBy=multi-user.target

啟用步驟


# 1. 確保 rc.local 存在且可執行
chmod +x /etc/rc.d/rc.local

# 2. 啟用兼容服務
systemctl enable rc-local.service
systemctl start rc-local.service

# 3. 驗證
systemctl status rc-local.service
journalctl -u rc-local.service

三、rc.local 寫法規範與避坑指南

規範說明錯誤範例正確範例
Shebang首行必須指定解釋器無首行#!/bin/bash
絕對路徑所有命令、腳本、配置檔使用絕對路徑./start.sh/opt/app/start.sh
環境變數明確 export PATH、HOME、LANG 等依賴繼承環境export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
後台執行長期運行程序必須 & 或 nohup,並重導向輸出/opt/app/servernohup /opt/app/server >/var/log/app.log 2>&1 &
PID 管理建議寫入 PID 檔,便於停止/重啟腳本管理無echo $! > /var/run/myapp.pid
錯誤處理關鍵步驟檢查返回碼,失敗記錄日誌並決定是否中止無檢查if ! mount /data; then logger "mount failed"; exit 1; fi
SELinux自定腳本需正確標籤或放行拒絕執行restorecon -v /etc/rc.d/rc.local

四、常見用途範例


#!/bin/bash
# /etc/rc.d/rc.local

export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
export LANG=en_US.UTF-8

# 1. 掛載遠端儲存
mount -t nfs 192.168.1.100:/data /mnt/nfs -o rw,hard,intr 2>>/var/log/rc.local.log

# 2. 設定核心參數(補充 sysctl.conf)
echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
echo 65535 > /proc/sys/fs/file-max

# 3. 啟動自製服務(非 systemd 管理)
nohup /opt/myapp/bin/server -c /opt/myapp/conf/app.yml \
     >>/var/log/myapp.log 2>&1 &
echo $! > /var/run/myapp.pid

# 4. 防火牆規則(若 firewalld 未就緒)
iptables -I INPUT -p tcp --dport 8080 -j ACCEPT

# 5. 同步硬體時鐘
hwclock --hctosys

exit 0

五、現代替代方案(systemd 原生)

新專案強烈建議直接撰寫 systemd 單元檔,優勢:

  • 依賴管理(After=、Requires=)
  • 自動重啟(Restart=on-failure)
  • 資源限制(MemoryLimit=、CPUQuota=)
  • 日誌整合(journalctl -u myservice)
  • 安全強化(PrivateTmp=yes、NoNewPrivileges=yes)

最小 systemd 單元範例


# /etc/systemd/system/myapp.service
[Unit]
Description=My Custom App
After=network.target

[Service]
Type=simple
User=appuser
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/bin/server -c /opt/myapp/conf/app.yml
Restart=on-failure
RestartSec=5
StandardOutput=append:/var/log/myapp.log
StandardError=append:/var/log/myapp.err

[Install]
WantedBy=multi-user.target

systemctl daemon-reload
systemctl enable --now myapp.service

六、總結

rc.local 是「逃生艙」而非「標準艙」。存量系統維持現狀無妨,但請遵守「絕對路徑、環境變數、後台管理、PID 記錄、SELinux」五大鐵律。增量開發請直接擁抱 systemd 單元檔,享受聲明式服務管理的完整紅利。

Copyright © Windows教程網 All Rights Reserved