本文目录导读:

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"
}
}
}
使用建议
- 定期执行:建议每天检查一次
- 日志记录:保留检查日志便于追踪
- 通知机制:只在有重要更新时发送通知
- 测试环境先执行:在生产环境使用前先在测试环境验证
- 考虑回滚方案:如果是自动更新,确保有回滚机制
根据您的具体需求(操作系统、包管理器、需要检查的软件等),可以选择或组合使用上述脚本。