用脚本检测更新并自动安装

wen 实用脚本 2

本文目录导读:

用脚本检测更新并自动安装

  1. Linux系统通用更新脚本
  2. Python自动检测更新脚本(通用)
  3. Windows系统更新脚本 (PowerShell)
  4. Docker容器自动更新脚本
  5. 使用说明
  6. 安全建议

我来为您提供一个自动检测更新并安装的脚本方案,根据不同的使用场景,这里提供几个版本:

Linux系统通用更新脚本

#!/bin/bash
# 自动更新脚本 - Linux通用版
# 适用于: Ubuntu/Debian, CentOS/RHEL, Fedora
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 日志函数
log_info() {
    echo -e "${GREEN}[INFO]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"
}
log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"
}
log_error() {
    echo -e "${RED}[ERROR]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"
}
# 检测操作系统类型
detect_os() {
    if [ -f /etc/os-release ]; then
        . /etc/os-release
        OS=$ID
        VER=$VERSION_ID
    else
        log_error "无法检测操作系统类型"
        exit 1
    fi
}
# 执行更新
perform_update() {
    log_info "开始检测系统更新..."
    case $OS in
        ubuntu|debian)
            log_info "检测到 Debian/Ubuntu 系统"
            sudo apt-get update
            if [ $? -ne 0 ]; then
                log_error "更新检查失败"
                return 1
            fi
            # 检查可更新包数量
            UPDATES=$(apt list --upgradable 2>/dev/null | grep -c upgradable)
            if [ $UPDATES -gt 0 ]; then
                log_info "发现 $UPDATES 个可更新包"
                sudo apt-get upgrade -y
                log_info "系统更新完成"
            else
                log_info "系统已经是最新"
            fi
            ;;
        centos|rhel|fedora)
            log_info "检测到 RedHat/CentOS/Fedora 系统"
            if command -v dnf &> /dev/null; then
                sudo dnf check-update
                if [ $? -eq 0 ] || [ $? -eq 100 ]; then
                    sudo dnf upgrade -y
                    log_info "系统更新完成"
                fi
            else
                sudo yum check-update
                if [ $? -eq 0 ] || [ $? -eq 100 ]; then
                    sudo yum update -y
                    log_info "系统更新完成"
                fi
            fi
            ;;
        *)
            log_error "不支持的操作系统: $OS"
            return 1
            ;;
    esac
}
# 主函数
main() {
    log_info "系统更新脚本启动"
    # 检查网络连接
    if ! ping -c 1 8.8.8.8 &> /dev/null; then
        log_error "网络连接失败,请检查网络"
        exit 1
    fi
    detect_os
    perform_update
    if [ $? -eq 0 ]; then
        log_info "脚本执行成功"
    else
        log_error "脚本执行失败"
        exit 1
    fi
}
# 执行主函数
main

Python自动检测更新脚本(通用)

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import sys
import subprocess
import platform
import logging
from datetime import datetime
# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('update.log'),
        logging.StreamHandler()
    ]
)
class SystemUpdater:
    def __init__(self):
        self.os_type = platform.system().lower()
        self.distro = self._detect_linux_distro()
    def _detect_linux_distro(self):
        """检测Linux发行版"""
        if self.os_type != 'linux':
            return None
        try:
            with open('/etc/os-release', 'r') as f:
                for line in f:
                    if line.startswith('ID='):
                        return line.strip().split('=')[1].strip('"')
        except FileNotFoundError:
            pass
        return None
    def check_updates(self):
        """检查可用更新"""
        logging.info("开始检查系统更新...")
        if self.os_type == 'linux':
            return self._check_linux_updates()
        elif self.os_type == 'windows':
            return self._check_windows_updates()
        else:
            logging.error(f"不支持的操作系统: {self.os_type}")
            return False
    def _check_linux_updates(self):
        """检查Linux系统更新"""
        try:
            if self.distro in ['ubuntu', 'debian']:
                # 更新软件源
                result = subprocess.run(
                    ['sudo', 'apt-get', 'update'],
                    capture_output=True,
                    text=True
                )
                # 检查可更新包
                result = subprocess.run(
                    ['apt', 'list', '--upgradable'],
                    capture_output=True,
                    text=True
                )
                upgrades = [line for line in result.stdout.split('\n') 
                           if 'upgradable' in line]
                if upgrades:
                    logging.info(f"发现 {len(upgrades)} 个可更新包")
                    return True, upgrades
                else:
                    logging.info("系统已经是最新")
                    return True, []
            elif self.distro in ['centos', 'rhel', 'fedora']:
                # 对于CentOS/Fedora系统的检查
                cmd = ['sudo', 'dnf', 'check-update']
                result = subprocess.run(cmd, capture_output=True, text=True)
                if 'No packages to update' in result.stdout:
                    logging.info("系统已经是最新")
                    return True, []
                else:
                    updates = [line for line in result.stdout.split('\n') 
                              if line and not line.startswith('Last')]
                    logging.info(f"发现 {len(updates)} 个可更新包")
                    return True, updates
            else:
                logging.error(f"不支持的Linux发行版: {self.distro}")
                return False, []
        except Exception as e:
            logging.error(f"检查更新失败: {str(e)}")
            return False, []
    def install_updates(self):
        """安装所有更新"""
        logging.info("开始安装更新...")
        if self.os_type == 'linux':
            return self._install_linux_updates()
        elif self.os_type == 'windows':
            return self._install_windows_updates()
        return False
    def _install_linux_updates(self):
        """安装Linux系统更新"""
        try:
            if self.distro in ['ubuntu', 'debian']:
                # 安装更新
                result = subprocess.run(
                    ['sudo', 'apt-get', 'upgrade', '-y'],
                    capture_output=True,
                    text=True,
                    timeout=3600  # 1小时超时
                )
                if result.returncode == 0:
                    logging.info("更新安装完成")
                    # 检查是否需要重启
                    if os.path.exists('/var/run/reboot-required'):
                        logging.warning("系统需要重启以完成更新")
                    return True
                else:
                    logging.error(f"更新安装失败: {result.stderr}")
                    return False
            elif self.distro in ['centos', 'rhel', 'fedora']:
                # 对于CentOS/Fedora系统
                cmd = ['sudo', 'dnf', 'upgrade', '-y']
                if self.distro in ['centos'] and self._get_centos_version() < 8:
                    cmd = ['sudo', 'yum', 'update', '-y']
                result = subprocess.run(
                    cmd,
                    capture_output=True,
                    text=True,
                    timeout=3600
                )
                if result.returncode == 0:
                    logging.info("更新安装完成")
                    return True
                else:
                    logging.error(f"更新安装失败: {result.stderr}")
                    return False
        except subprocess.TimeoutExpired:
            logging.error("更新安装超时")
            return False
        except Exception as e:
            logging.error(f"安装更新失败: {str(e)}")
            return False
    def run(self):
        """运行更新检查与安装"""
        logging.info(f"=== 系统更新检查开始 ({datetime.now().strftime('%Y-%m-%d %H:%M:%S')}) ===")
        # 检查更新
        success, updates = self.check_updates()
        if not success:
            logging.error("更新检查失败")
            return False
        # 如果有更新,自动安装
        if updates:
            logging.info(f"发现 {len(updates)} 个更新,开始自动安装...")
            if self.install_updates():
                logging.info("所有更新安装完成")
                return True
            else:
                logging.error("部分更新安装失败")
                return False
        else:
            logging.info("没有需要安装的更新")
            return True
# 主函数
def main():
    updater = SystemUpdater()
    updater.run()
if __name__ == "__main__":
    main()

Windows系统更新脚本 (PowerShell)

# Windows自动更新脚本
# 保存为: auto-update.ps1
# 设置执行策略
$ErrorActionPreference = "Stop"
# 日志函数
function Write-Log {
    param([string]$Message, [string]$Level = "INFO")
    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    Write-Host "[$timestamp] [$Level] $Message"
    # 同时写入日志文件
    $logMessage = "[$timestamp] [$Level] $Message"
    Add-Content -Path "update.log" -Value $logMessage
}
# 检查管理员权限
function Check-AdminPrivileges {
    $currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
    $principal = New-Object Security.Principal.WindowsPrincipal($currentUser)
    if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
        Write-Log -Message "需要管理员权限运行此脚本" -Level "ERROR"
        return $false
    }
    return $true
}
# 检查Windows更新
function Check-WindowsUpdates {
    Write-Log -Message "开始检查Windows更新..."
    try {
        # 创建Windows Update会话
        $UpdateSession = New-Object -ComObject Microsoft.Update.Session
        $UpdateSearcher = $UpdateSession.CreateUpdateSearcher()
        # 搜索更新
        $SearchResult = $UpdateSearcher.Search("IsInstalled=0 and Type='Software'")
        if ($SearchResult.Updates.Count -eq 0) {
            Write-Log -Message "没有可用的更新"
            return $null
        }
        Write-Log -Message "发现 $($SearchResult.Updates.Count) 个可用更新"
        # 列出更新
        foreach ($Update in $SearchResult.Updates) {
            Write-Log -Message "  - $($Update.Title)"
        }
        return $SearchResult.Updates
    } catch {
        Write-Log -Message "检查更新失败: $_" -Level "ERROR"
        return $null
    }
}
# 安装Windows更新
function Install-WindowsUpdates {
    param([object]$Updates)
    if ($null -eq $Updates) {
        Write-Log -Message "没有需要安装的更新"
        return $true
    }
    Write-Log -Message "开始安装更新..."
    try {
        $UpdateSession = New-Object -ComObject Microsoft.Update.Session
        $UpdateDownloader = $UpdateSession.CreateUpdateDownloader()
        $UpdateDownloader.Updates = $Updates
        # 下载更新
        Write-Log -Message "正在下载更新..."
        $DownloadResult = $UpdateDownloader.Download()
        if ($DownloadResult.ResultCode -ne 2) { # 2 = Downloaded
            Write-Log -Message "下载更新失败" -Level "ERROR"
            return $false
        }
        # 安装更新
        Write-Log -Message "正在安装更新..."
        $UpdateInstaller = $UpdateSession.CreateUpdateInstaller()
        $UpdateInstaller.Updates = $Updates
        $InstallationResult = $UpdateInstaller.Install()
        if ($InstallationResult.ResultCode -eq 2) { # 2 = Succeeded
            Write-Log -Message "更新安装成功完成"
            # 检查是否需要重启
            if ($InstallationResult.RebootRequired) {
                Write-Log -Message "系统需要重启以完成更新" -Level "WARNING"
            }
            return $true
        } else {
            Write-Log -Message "更新安装失败,结果代码: $($InstallationResult.ResultCode)" -Level "ERROR"
            return $false
        }
    } catch {
        Write-Log -Message "安装更新失败: $_" -Level "ERROR"
        return $false
    }
}
# 主程序
function Main {
    Write-Log -Message "=== Windows自动更新脚本开始 ==="
    # 检查管理员权限
    if (-not (Check-AdminPrivileges)) {
        exit 1
    }
    # 检查更新
    $updates = Check-WindowsUpdates
    if ($null -eq $updates) {
        Write-Log -Message "系统已经是最新"
        return
    }
    # 安装更新
    $result = Install-WindowsUpdates -Updates $updates
    if ($result) {
        Write-Log -Message "更新过程完成"
        # 如果需要重启,询问用户
        if ($InstallationResult.RebootRequired) {
            $response = Read-Host "系统需要重启,是否立即重启? (Y/N)"
            if ($response -eq 'Y' -or $response -eq 'y') {
                Restart-Computer -Force
            }
        }
    } else {
        Write-Log -Message "更新过程失败" -Level "ERROR"
    }
}
# 执行主程序
Main

Docker容器自动更新脚本

#!/bin/bash
# Docker容器自动更新脚本
# 配置
CONTAINER_NAME="your-container-name"
IMAGE_NAME="your-image-name"
BACKUP_DIR="/backup/docker"
# 颜色
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# 日志
log() {
    echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1"
}
error() {
    echo -e "${RED}[ERROR]${NC} $1"
}
# 检查Docker是否运行
check_docker() {
    if ! docker info &> /dev/null; then
        error "Docker未运行"
        exit 1
    fi
}
# 备份当前容器
backup_container() {
    local container=$1
    local backup_file="${BACKUP_DIR}/${container}_$(date +%Y%m%d_%H%M%S).tar"
    log "备份容器 $container ..."
    docker commit $container "${container}:backup"
    docker save -o $backup_file "${container}:backup"
    log "备份完成: $backup_file"
}
# 检查镜像更新
check_image_update() {
    local image=$1
    log "检查镜像更新: $image"
    # 拉取最新镜像
    docker pull $image
    # 检查是否有更新
    local current=$(docker images $image --format "{{.Tag}}" | head -n1)
    local latest=$(docker images $image --format "{{.Tag}}" | tail -n1)
    if [ "$current" != "$latest" ]; then
        log "发现新版本: $latest"
        return 0
    else
        log "当前已是最新版本"
        return 1
    fi
}
# 更新容器
update_container() {
    local container=$1
    local image=$2
    log "开始更新容器 $container ..."
    # 获取当前容器配置
    local config=$(docker inspect $container --format '{{json .}}')
    # 停止并删除旧容器
    docker stop $container
    docker rm $container
    # 使用相同配置创建新容器
    # 注意: 这里需要根据实际情况修改参数
    docker run -d \
        --name $container \
        --restart unless-stopped \
        $image
    log "容器更新完成"
}
# 清理旧镜像
cleanup_images() {
    log "清理旧镜像..."
    docker image prune -f
    log "清理完成"
}
# 主函数
main() {
    log "Docker自动更新脚本启动"
    check_docker
    # 备份当前容器
    backup_container $CONTAINER_NAME
    # 检查更新
    if check_image_update $IMAGE_NAME; then
        # 更新容器
        update_container $CONTAINER_NAME $IMAGE_NAME
        # 清理
        cleanup_images
        log "更新完成"
    else
        log "无需更新"
    fi
}
# 执行
main

使用说明

Linux脚本使用:

# 1. 保存脚本为 update.sh
# 2. 添加执行权限
chmod +x update.sh
# 3. 运行脚本
sudo ./update.sh
# 4. 设置定时任务(每天凌晨2点更新)
# 编辑 crontab
sudo crontab -e
# 添加以下行
0 2 * * * /path/to/update.sh >> /var/log/auto-update.log 2>&1

Python脚本使用:

# 1. 保存脚本为 auto_update.py
# 2. 运行脚本
python3 auto_update.py
# 3. 设置systemd定时器(可选)

Windows脚本使用:

# 1. 以管理员身份运行PowerShell
# 2. 设置执行策略
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
# 3. 运行脚本
.\auto-update.ps1
# 4. 设置任务计划程序自动运行

Docker脚本使用:

# 1. 保存脚本为 docker_update.sh
# 2. 修改配置变量
# 3. 运行脚本
sudo ./docker_update.sh

安全建议

  1. 备份重要数据:确保在自动更新前已有备份
  2. 测试环境验证:先在测试环境测试更新
  3. 设置回滚机制:保留前一个版本的备份
  4. 监控更新过程:记录日志并监控更新结果
  5. 选择性更新:某些关键软件可能需要手动更新

这些脚本提供了自动检测和安装更新的基本框架,您可以根据实际需求进行修改和定制。

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