用 Shell 腳本自動化系統更新 文章首圖

用 Shell 腳本自動化系統更新

用 Shell 腳本自動化系統更新

在日常的系統管理工作中,保持操作系統的安全與穩定是首要任務。然而,對於管理多台伺服器或工作站的管理員來說,手動執行 apt updateapt upgrade 不僅耗時,還容易因為遺忘而導致安全漏洞。透過撰寫 Shell 腳本來自動化系統更新流程,不僅能節省時間,更能確保更新過程的可追蹤性與一致性。本文將介紹如何撰寫一個簡單但強大的 Shell 腳本,用於自動化 Ubuntu 22.04 或 Debian 12 的系統更新。

自動化腳本的核心邏輯

一個完整的系統更新腳本通常包含三個主要階段:環境檢查、執行更新、以及結果回報。為了讓腳本更具實用性,我們還需要加入錯誤處理機制,確保在出現異常時能夠正確退出並記錄日誌。

首先,我們需要確保腳本擁有足夠的權限來執行系統級別的更新操作。因此,檢查當前使用者是否為 root 是第一步。其次,在執行更新前,最好先檢查是否有待更新的套件列表,以避免不必要的網路請求。最後,更新完成後,發送通知或記錄日誌是驗證更新成功的重要步驟。

完整可執行腳本範例

以下是為 Ubuntu 22.04 和 Debian 12 設計的自動化更新腳本範例。請將以下程式碼保存為 auto_update.sh,並賦予執行權限。

#!/bin/bash

# 設定變數
LOG_FILE="/var/log/auto_update.log"
EMAIL_TO="admin@example.com" # 請替換為實際的電子郵件地址

# 檢查是否為 root 使用者
if [ "$(id -u)" -ne 0 ]; then
    echo "錯誤:請以 root 權限執行此腳本" >&2
    exit 1
fi

# 初始化日誌
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 開始系統更新..." >> "$LOG_FILE"

# 更新套件列表
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 正在更新套件列表..." >> "$LOG_FILE"
apt-get update -y >> "$LOG_FILE" 2>&1

if [ $? -ne 0 ]; then
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] 套件列表更新失敗,請檢查網路或來源設定。" >> "$LOG_FILE"
    exit 1
fi

# 檢查是否有可更新的套件
UPGRADABLE_COUNT=$(apt list --upgradable 2>/dev/null | grep -c "upgradable")

if [ "$UPGRADABLE_COUNT" -eq 0 ]; then
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] 系統已是最新狀態,無需更新。" >> "$LOG_FILE"
    exit 0
fi

# 執行系統更新
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 正在安裝更新 ($UPGRADABLE_COUNT 個套件)..." >> "$LOG_FILE"
DEBIAN_FRONTEND=noninteractive apt-get upgrade -y >> "$LOG_FILE" 2>&1

if [ $? -eq 0 ]; then
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] 系統更新成功完成。" >> "$LOG_FILE"
    # 可選:發送通知郵件 (需安裝 mailutils 或配置 MTA)
    # echo "系統更新已完成" | mail -s "系統更新報告" "$EMAIL_TO"
else
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] 系統更新過程中發生錯誤,請檢查日誌 $LOG_FILE。" >> "$LOG_FILE"
    exit 1
fi

# 清理暫存檔案
apt-get autoremove -y >> "$LOG_FILE" 2>&1
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 腳本執行完畢。" >> "$LOG_FILE"

腳本說明與部署

  1. 權限檢查:腳本開頭使用 id -u 檢查當前使用者 ID 是否為 0(即 root)。若非 root 執行,則輸出錯誤訊息並退出,避免權限不足導致的未預期中斷。
  2. 日誌記錄:所有輸出均追加至 /var/log/auto_update.log。這對於後續除錯和審計至關重要。
  3. 非互動式模式:在執行 apt-get upgrade 時,我們設定了 DEBIAN_FRONTEND=noninteractive。這是 Debian/Ubuntu 系統中的關鍵設定,它能防止系統在更新過程中彈出對話框詢問使用者是否重新啟動服務,確保腳本能無人值守地自動執行。
  4. 自動清理:更新結束後,執行 apt-get autoremove 可以移除不再需要的依賴套件,節省磁碟空間。

將此腳本部署後,您可以使用 crontab 設定定期執行。例如,每天凌晨 3 點自動執行:

0 3 * * * /bin/bash /path/to/auto_update.sh

常見問題

1. 更新過程中出現「需要重新啟動」的提示,腳本會卡住嗎? 不會。由於我們在腳本中明確設定了 DEBIAN_FRONTEND=noninteractiveapt 會自動採用預設選項(通常是「是」),不會等待使用者輸入。但如果系統核心更新後需要重新啟動,腳本本身並不會自動重啟機器。若需自動重啟,可額外加入判斷邏輯,檢查 /var/run/reboot-required 檔案是否存在。

2. 如何確保腳本只在特定時間段執行,避免影響業務高峰? 除了使用 crontab 設定精確時間外,還可以在腳本內部加入時間檢查邏輯。例如,檢查當前小時是否大於 2 且小於 6,若不在範圍內則直接退出。這樣可以作為雙重保險,防止因手動觸發或排程錯誤導致的業務高峰時段更新。

小結

透過撰寫 Shell 腳本自動化系統更新,我們不僅提升了系統管理的效率,更增強了環境的一致性與安全性。這個範例腳本雖然簡潔,但涵蓋了權限檢查、日誌記錄、非互動式更新以及錯誤處理等關鍵要素,非常適合初學者與進階管理員參考使用。建議根據實際需求,進一步擴展其功能,例如加入更新前的備份步驟或更複雜的通知機制。