如何编写定期检查更新的脚本

wen 实用脚本 2

本文目录导读:

如何编写定期检查更新的脚本

  1. Linux系统下的更新检查脚本
  2. Python脚本(跨平台)
  3. 设置定时执行
  4. Docker容器更新检查
  5. 配置文件示例
  6. 使用建议

Linux系统下的更新检查脚本

Shell脚本(适用于apt包管理器)

#!/bin/bash
# 系统更新检查脚本
# 适用于Debian/Ubuntu系统
LOG_FILE="/var/log/update-check.log"
DATE=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$DATE] 开始检查系统更新..." >> $LOG_FILE
# 更新包列表
apt update 2>&1 >> $LOG_FILE
# 检查可更新的包数量
UPDATES=$(apt list --upgradable 2>/dev/null | grep -c upgradable)
if [ $UPDATES -gt 0 ]; then
    echo "[$DATE] 发现 $UPDATES 个可用更新" >> $LOG_FILE
    echo "[$DATE] 可用更新列表:" >> $LOG_FILE
    apt list --upgradable 2>/dev/null >> $LOG_FILE
    # 如果需要自动安装,取消下面注释
    # apt upgrade -y 2>&1 >> $LOG_FILE
else
    echo "[$DATE] 系统已为最新" >> $LOG_FILE
fi

使用systemd定时器

创建定时器文件 /etc/systemd/system/check-updates.service

[Unit]
Description=检查系统更新
[Service]
Type=oneshot
ExecStart=/usr/local/bin/check-updates.sh

创建定时器 /etc/systemd/system/check-updates.timer

[Unit]
Description=每日检查系统更新
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target

Python脚本(跨平台)

#!/usr/bin/env python3
"""
跨平台更新检查脚本
支持多个软件源检查
"""
import subprocess
import logging
import os
from datetime import datetime
import json
class UpdateChecker:
    def __init__(self, config_file="update_config.json"):
        self.logger = self.setup_logging()
        self.config = self.load_config(config_file)
    def setup_logging(self):
        logging.basicConfig(
            level=logging.INFO,
            format='%(asctime)s - %(levelname)s - %(message)s',
            handlers=[
                logging.FileHandler('update_check.log'),
                logging.StreamHandler()
            ]
        )
        return logging.getLogger(__name__)
    def load_config(self, config_file):
        """加载配置文件"""
        default_config = {
            "check_interval_hours": 24,
            "auto_update": False,
            "notify_method": "log",  # log, email, slack
            "packages_to_check": []
        }
        if os.path.exists(config_file):
            with open(config_file, 'r') as f:
                return {**default_config, **json.load(f)}
        return default_config
    def check_system_updates(self):
        """检查系统更新"""
        self.logger.info("开始检查系统更新...")
        try:
            if os.name == 'nt':  # Windows
                return self.check_windows_updates()
            else:  # Linux/Mac
                return self.check_linux_updates()
        except Exception as e:
            self.logger.error(f"检查更新失败: {e}")
            return False
    def check_linux_updates(self):
        """检查Linux系统更新"""
        try:
            # 更新包列表
            subprocess.run(['apt', 'update'], check=False, capture_output=True)
            # 检查可用更新
            result = subprocess.run(
                ['apt', 'list', '--upgradable'],
                capture_output=True,
                text=True
            )
            updates = [line for line in result.stdout.split('\n') 
                      if '/stable' in line or '/security' in line]
            if updates:
                self.logger.info(f"发现 {len(updates)} 个可用更新")
                for update in updates[:10]:  # 显示前10个
                    self.logger.info(f"  - {update}")
                return True
            else:
                self.logger.info("系统已为最新")
                return False
        except FileNotFoundError:
            self.logger.warning("apt命令不可用,尝试使用其他包管理器")
            return self.check_rpm_updates()
    def check_windows_updates(self):
        """检查Windows更新"""
        try:
            import win32com.client
            update_session = win32com.client.Dispatch("Microsoft.Update.Session")
            update_searcher = update_session.CreateUpdateSearcher()
            search_result = update_searcher.Search("IsInstalled=0")
            if search_result.Updates.Count > 0:
                self.logger.info(f"发现 {search_result.Updates.Count} 个可用更新")
                for update in search_result.Updates:
                    self.logger.info(f"  - {update.Title}")
                return True
            else:
                self.logger.info("系统已为最新")
                return False
        except ImportError:
            self.logger.error("需要安装pywin32来检查Windows更新")
            return False
    def check_python_packages(self):
        """检查Python包更新"""
        self.logger.info("检查Python包更新...")
        try:
            # 获取已安装包列表
            result = subprocess.run(
                ['pip', 'list', '--outdated', '--format=json'],
                capture_output=True,
                text=True
            )
            if result.returncode == 0:
                outdated_packages = json.loads(result.stdout)
                if outdated_packages:
                    self.logger.info(f"发现 {len(outdated_packages)} 个过时包")
                    for pkg in outdated_packages:
                        self.logger.info(
                            f"  - {pkg['name']}: {pkg['version']} -> {pkg['latest_version']}"
                        )
                    return True
                else:
                    self.logger.info("所有Python包已为最新")
                    return False
        except Exception as e:
            self.logger.error(f"检查Python包更新失败: {e}")
            return False
    def send_notification(self, message):
        """发送更新通知"""
        method = self.config.get('notify_method', 'log')
        if method == 'email':
            self.send_email_notification(message)
        elif method == 'slack':
            self.send_slack_notification(message)
        else:
            self.logger.info(f"通知: {message}")
def main():
    checker = UpdateChecker()
    # 检查系统更新
    has_updates = checker.check_system_updates()
    # 检查Python包更新
    has_python_updates = checker.check_python_packages()
    if has_updates or has_python_updates:
        checker.send_notification("发现可用更新,请检查日志")
if __name__ == "__main__":
    main()

设置定时执行

Linux cron任务

# 编辑crontab
crontab -e
# 每天凌晨2点执行检查
0 2 * * * /usr/local/bin/check-updates.sh
# 或使用更复杂的调度
# 每小时检查一次
0 * * * * /usr/local/bin/check-updates.sh

使用at命令(一次性定时)

# 2小时后执行
echo "/usr/local/bin/check-updates.sh" | at now + 2 hours
# 明天特定时间执行
echo "/usr/local/bin/check-updates.sh" | at 10:00 tomorrow

Docker容器更新检查

#!/bin/bash
# Docker容器更新检查脚本
# 检查所有运行中的容器是否有更新
check_docker_updates() {
    local containers=$(docker ps --format "{{.Names}}")
    for container in $containers; do
        echo "检查容器: $container"
        # 获取容器使用的镜像
        local image=$(docker inspect --format='{{.Config.Image}}' $container)
        # 拉取最新镜像
        docker pull $image > /dev/null 2>&1
        # 比较新旧镜像ID
        local old_id=$(docker inspect --format='{{.Image}}' $container)
        local new_id=$(docker images --format='{{.ID}}' $image)
        if [ "$old_id" != "$new_id" ]; then
            echo "  [更新可用] $image"
            # 如果需要自动更新,取消注释
            # docker stop $container
            # docker rm $container
            # docker run -d --name $container $image
        else
            echo "  [最新] $image"
        fi
    done
}
check_docker_updates

配置文件示例

创建 update_config.json

{
    "check_interval_hours": 24,
    "auto_update": false,
    "notify_method": "log",
    "packages_to_check": [
        "nginx",
        "mysql-server",
        "python3"
    ],
    "exclude_packages": [
        "libreoffice*",
        "thunderbird"
    ],
    "notify_config": {
        "email": {
            "smtp_server": "smtp.gmail.com",
            "port": 587,
            "username": "your-email@gmail.com",
            "password": "your-password",
            "recipients": ["admin@example.com"]
        },
        "slack": {
            "webhook_url": "https://hooks.slack.com/services/xxx"
        }
    }
}

使用建议

  1. 定期执行:建议每天检查一次
  2. 日志记录:保留检查日志便于追踪
  3. 通知机制:只在有重要更新时发送通知
  4. 测试环境先执行:在生产环境使用前先在测试环境验证
  5. 考虑回滚方案:如果是自动更新,确保有回滚机制

根据您的具体需求(操作系统、包管理器、需要检查的软件等),可以选择或组合使用上述脚本。

抱歉,评论功能暂时关闭!