原创内容,转载请注明出处:https://www.myzhenai.com.cn/post/5033.html
前些天,Linux系统接连曝出了几个高危漏洞,甚至有内核漏洞,因为有时候我们在遇到这些漏洞的时候,不能及时更新系统
这将给我们的服务器带来末知的危险
所以我这里写了一个无人值守,自动更新的Shell脚本
脚本的原理是,定时自动 apt update && apt upgrade
但是脚本还可以判断系统中的Kernel数量,只保留最近的两个内核,其他的就卸载删除了
同时会自动清理不用的依赖文件包,这个脚本deepin系统慎用
因为,在deepin下,apt autoremove 会卸载很多关联的依赖,造成系统崩溃
将脚本复制到服务器上,保存为.sh后缀的文件
然后,crontab -e 设置定时任务,让脚本定时执行就可以了
以后,就算自己不登录服务器,服务器也会自动更新
#!/bin/bash
set -eu
#############################################################################
# Debian 12 服务器自动更新脚本(无人值守版)
# 功能:更新系统、升级内核、自动检测并删除旧内核
# 作者:RucLinux
#############################################################################
# 配置区域
LOG_FILE="/var/log/debian-update.log"
KEEP_KERNEL_COUNT=2 # 保留的内核数量(包括当前使用的)
# 日志函数(无颜色,适合文件记录)
log_message() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
error_exit() {
log_message "错误: $1"
exit 1
}
# 检查是否以 root 运行
if [ "$EUID" -ne 0 ]; then
error_exit "请以 root 用户运行此脚本"
fi
# 检查必要工具
check_tools() {
log_message "检查必要工具..."
local tools=("curl" "wget" "awk" "sed" "grep")
for tool in "${tools[@]}"; do
if ! command -v "$tool" &>/dev/null; then
error_exit "缺少必要工具: $tool"
fi
done
log_message "工具检查完成"
}
# 1. 更新软件包列表
update_package_list() {
log_message "更新软件包列表..."
apt update >>"$LOG_FILE" 2>&1 || error_exit "apt update 失败"
log_message "软件包列表更新完成"
}
# 2. 升级已安装的软件包
upgrade_packages() {
log_message "升级已安装软件包..."
apt upgrade -y >>"$LOG_FILE" 2>&1 || error_exit "apt upgrade 失败"
log_message "软件包升级完成"
}
# 3. 执行完整升级(包含依赖变化)
full_upgrade() {
log_message "执行完整升级..."
apt full-upgrade -y >>"$LOG_FILE" 2>&1 || error_exit "apt full-upgrade 失败"
log_message "完整升级完成"
}
# 4. 清理不再需要的包
clean_unused_packages() {
log_message "清理不再需要的包..."
apt autoremove --purge -y >>"$LOG_FILE" 2>&1 || log_message "警告: autoremove 执行失败"
apt autoclean -y >>"$LOG_FILE" 2>&1 || log_message "警告: autoclean 执行失败"
apt clean -y >>"$LOG_FILE" 2>&1 || log_message "警告: clean 执行失败"
log_message "包清理完成"
}
# 5. 自动删除旧内核(核心功能)
remove_old_kernels() {
log_message "开始清理旧内核..."
# 获取当前运行的内核版本(如 6.1.0-18-amd64 取 6.1.0-18)
local current_kernel=$(uname -r | cut -d'-' -f1,2)
log_message "当前运行的内核: $current_kernel"
# 获取所有已安装的内核包列表(按版本排序)
local kernel_packages=$(dpkg -l | awk '/^ii linux-image-[0-9]/{print $2}' | sort -V)
if [ -z "$kernel_packages" ]; then
log_message "没有找到内核包"
return 0
fi
local total_kernels=$(echo "$kernel_packages" | wc -l)
local kernels_to_remove=$((total_kernels - KEEP_KERNEL_COUNT))
if [ $kernels_to_remove -le 0 ]; then
log_message "当前内核数量 ($total_kernels) 未超过保留数量 ($KEEP_KERNEL_COUNT),无需清理"
return 0
fi
log_message "发现 $total_kernels 个内核包,将保留最新的 $KEEP_KERNEL_COUNT 个"
# 找出要删除的内核(最旧的几个)
local kernels_to_delete=$(echo "$kernel_packages" | head -n $kernels_to_remove)
log_message "以下内核将被删除:"
echo "$kernels_to_delete" | while read kernel; do
log_message " - $kernel"
done
# 执行删除(跳过当前运行的内核)
echo "$kernels_to_delete" | while read kernel; do
if [[ "$kernel" == *"$current_kernel"* ]]; then
log_message "跳过当前运行的内核: $kernel"
continue
fi
log_message "删除内核: $kernel"
apt purge -y "$kernel" >>"$LOG_FILE" 2>&1 || log_message "警告: 删除 $kernel 失败"
# 删除相关的模块目录
local kernel_version=$(echo "$kernel" | sed 's/linux-image-//')
if [ -d "/lib/modules/$kernel_version" ]; then
rm -rf "/lib/modules/$kernel_version"
log_message "删除模块目录: /lib/modules/$kernel_version"
fi
# 删除/boot中的相关文件
for file in /boot/vmlinuz-$kernel_version /boot/initrd.img-$kernel_version /boot/System.map-$kernel_version /boot/config-$kernel_version; do
[ -f "$file" ] && rm -f "$file" && log_message "删除: $file"
done
done
# 再次运行 autoremove 确保清理干净
apt autoremove --purge -y >>"$LOG_FILE" 2>&1
log_message "旧内核清理完成"
# 更新 GRUB 配置
if command -v update-grub &>/dev/null; then
log_message "更新 GRUB 配置..."
update-grub >>"$LOG_FILE" 2>&1
fi
}
# 6. 清理临时文件和日志
clean_temp_files() {
log_message "清理临时文件..."
# 清理 /tmp 中超过7天的文件
find /tmp -type f -atime +7 -delete 2>/dev/null || true
# 清理 journal 日志,保留最近2周
journalctl --vacuum-time=2weeks >>"$LOG_FILE" 2>&1 || true
# 清理旧的日志文件
find /var/log -name "*.log.*" -mtime +30 -delete 2>/dev/null || true
find /var/log -name "*.gz" -mtime +30 -delete 2>/dev/null || true
log_message "临时文件清理完成"
}
# 7. 检查是否需要重启(仅记录,不自动重启)
check_reboot_needed() {
if [ -f /var/run/reboot-required ]; then
log_message "系统需要重启以应用更新"
cat /var/run/reboot-required 2>/dev/null | while read line; do
log_message " - $line"
done
log_message "请手动重启系统以完成更新"
else
log_message "无需重启"
fi
}
# 8. 生成系统报告
generate_report() {
log_message "生成系统报告..."
local report_file="/tmp/system-report-$(date +%Y%m%d).txt"
{
echo "========================================="
echo "Debian 12 系统更新报告"
echo "生成时间: $(date '+%Y-%m-%d %H:%M:%S')"
echo "========================================="
echo ""
echo "系统信息:"
echo " - 主机名: $(hostname)"
echo " - 内核版本: $(uname -r)"
echo " - 系统版本: $(lsb_release -d 2>/dev/null | cut -f2 || cat /etc/debian_version)"
echo ""
echo "磁盘使用情况:"
df -h | grep -E '^/dev/' | while read line; do
echo " $line"
done
echo ""
echo "已安装内核:"
dpkg -l | awk '/^ii linux-image-[0-9]/{print " - " $2}' | sort -V
echo ""
echo "更新日志:"
tail -20 "$LOG_FILE"
} > "$report_file"
log_message "系统报告已生成: $report_file"
}
# 主函数
main() {
log_message "========== 开始 Debian 12 自动更新 =========="
check_tools
update_package_list
upgrade_packages
full_upgrade
clean_unused_packages
remove_old_kernels
clean_temp_files
generate_report
check_reboot_needed
log_message "========== Debian 12 自动更新完成 =========="
}
main "$@"
脚本会在/tmp/ 目录下生成一个txt的报告文件,如果有更新的话,会将更新的内容反馈回来,如果没有更新,就不反馈
root@dZ:~# cat /tmp/system-report-$(date +%Y%m%d).txt ========================================= Debian 12 系统更新报告 生成时间: 2026-05-26 14:43:50 ========================================= 系统信息: - 主机名: dZ - 内核版本: 6.1.0-48-amd64 - 系统版本: Debian GNU/Linux 12 (bookworm) 磁盘使用情况: /dev/vda3 79G 26G 50G 34% / /dev/vda2 189M 12M 177M 7% /boot/efi 已安装内核: - linux-image-6.1.0-47-amd64 - linux-image-6.1.0-48-amd64 更新日志: WARNING: apt does not have a stable CLI interface. Use with caution in scripts. Reading package lists... Building dependency tree... Reading state information... WARNING: apt does not have a stable CLI interface. Use with caution in scripts. [2026-05-26 14:43:50] 包清理完成 [2026-05-26 14:43:50] 开始清理旧内核... [2026-05-26 14:43:50] 当前运行的内核: 6.1.0-48 [2026-05-26 14:43:50] 当前内核数量 (2) 未超过保留数量 (2),无需清理 [2026-05-26 14:43:50] 清理临时文件... Vacuuming done, freed 0B of archived journals from /run/log/journal. Vacuuming done, freed 0B of archived journals from /var/log/journal. Deleted archived journal /var/log/journal/edfdedf5bc6d4c37b695d3cc884f6a78/system@54b6f1ef06be4fd482281ee1b4a4f8bf-00000000001b9e1a-000651974af965cd.journal (42.7M). Vacuuming done, freed 42.7M of archived journals from /var/log/journal/edfdedf5bc6d4c37b695d3cc884f6a78. [2026-05-26 14:43:50] 临时文件清理完成 [2026-05-26 14:43:50] 生成系统报告...
发布时 IP 属地:海南省海口市


0 条评论
表情面板
您的邮箱地址和手机号码不会被公开。 必填项已用 * 标注