适用环境
- 操作系统: Debian 12 (Bookworm)。同样适用于其他基于 systemd 的现代 Linux 发行版,如 Ubuntu 22.04+, CentOS 8+, Rocky Linux 8+。
- 所需权限:
root或具有sudo能力的用户。 - 前置知识: 熟悉基本的 Linux 命令行操作和文本编辑器(如
nano或vim)。
教程目标
本教程将引导您完成以下任务:
- 创建一个安全、模块化的 Bash 脚本,用于执行常规的系统清理操作。
- 配置一个 systemd Service 单元来运行该脚本。
- 配置一个 systemd Timer 单元来周期性地触发该 Service,实现全自动化维护。
步骤一:创建清理脚本 (cleanup.sh)
此脚本是自动化任务的核心,负责执行所有清理操作。我们将它放置在 /usr/local/bin 目录,这是存放本地管理员脚本的标准位置。
1. 创建并编辑脚本文件:
sudo nano /usr/local/bin/cleanup.sh
2. 粘贴以下脚本内容:
#!/bin/bash
# Debian/Ubuntu 服务器安全清理脚本
# 功能: 清理 APT 缓存、孤立包、旧日志、Docker 资源等。
#
# 错误处理: `set -e` 确保任何命令失败时脚本立即退出。
set -e
# --- 安全检查: 强制以 root 权限运行 ---
if [[ $EUID -ne 0 ]]; then
echo "错误: 此脚本必须以 root 权限运行。" >&2
exit 1
fi
echo "系统清理任务启动于: $(date)"
echo "-----------------------------------------"
# 模块 1: 清理 APT
echo "[APT] 正在清理软件包缓存和无用依赖..."
apt-get update -y > /dev/null
apt-get clean -y
apt-get autoremove --purge -y
# 模块 2: 清理 Systemd Journal
echo "[Journald] 正在清理日志..."
journalctl --vacuum-size=200M
# 模块 3: 清理已归档的旧日志
# 此命令仅删除 /var/log/ 下被 logrotate 归档过的、7天前的日志文件
# (如 .gz 压缩包或 .log.1, .log.2 等),不会影响当前活动的日志文件。
echo "[Logrotate] 正在清理旧的归档日志..."
find /var/log -type f -regex '.*\.\(gz\|log\.[0-9].*\)$' -mtime +7 -delete
# 模块 4: 清理 Docker (如果已安装)
if command -v docker &> /dev/null; then
echo "[Docker] 正在清理未使用的容器、网络和镜像..."
docker system prune -af
fi
# 模块 5: 清理 /tmp 目录
# 仅删除7天以上未被访问过的临时文件。
echo "[TMP] 正在清理旧的临时文件..."
find /tmp -type f -atime +7 -delete
echo "-----------------------------------------"
echo "系统清理任务完成于: $(date)"
exit 0
3. 赋予脚本执行权限:
sudo chmod +x /usr/local/bin/cleanup.sh
步骤二:配置 Systemd 单元
Systemd 通过单元(Unit)文件来管理资源。我们需要创建两个单元:Service 和 Timer。
cleanup.service: 定义要做什么(What)。它负责执行我们的脚本。cleanup.timer: 定义何时去做(When)。它负责按计划触发 Service。
1. 创建 Service 单元:
sudo nano /etc/systemd/system/cleanup.service
内容如下:
[Unit]
Description=执行常规系统清理脚本
[Service]
Type=oneshot
ExecStart=/usr/local/bin/cleanup.sh
Type=oneshot: 表明这是一个执行单个任务的短时服务。ExecStart: 指定要运行的命令的绝对路径。
2. 创建 Timer 单元:
sudo nano /etc/systemd/system/cleanup.timer
内容如下:
[Unit]
Description=每周日凌晨3点运行系统清理任务
[Timer]
# OnCalendar 定义了定时规则。格式: DayOfWeek YYYY-MM-DD HH:MM:SS
# `Sun *-*-* 03:00:00` 表示每周日的凌晨3点。
OnCalendar=Sun *-*-* 03:00:00
# 如果预定时间点服务器处于关机状态,则在下次启动后立即执行一次错过的任务。
Persistent=true
[Install]
WantedBy=timers.target
OnCalendar: 强大的日历计时器,支持灵活的时间和日期匹配。Persistent=true: 确保任务不会因为服务器停机而永久错过。
步骤三:部署与验证
完成文件创建后,我们需要让 systemd 识别它们,并验证其功能是否正常。
1. 重载 Systemd 守护进程:
此命令会扫描并加载所有新的或已修改的单元文件。
sudo systemctl daemon-reload
2. 手动测试 Service (推荐):
在启用定时器之前,先手动触发一次 Service 来确认脚本可以无误地执行。
# 启动服务
sudo systemctl start cleanup.service
# 检查服务的最后一次运行状态
systemctl status cleanup.service
如果输出显示 Active: inactive (dead) 和 status=0/SUCCESS,并且日志正常,则表示测试通过。
3. 启用并启动 Timer:
此命令会使 Timer 在系统启动时自动激活,并立即开始计时。
sudo systemctl enable --now cleanup.timer
4. 验证 Timer 状态:
检查所有活动的定时器,确认我们的任务已正确调度。
systemctl list-timers
您应该能在列表中看到 cleanup.timer,以及它下一次预定的运行时间 (NEXT 列)。
# 预期输出示例
NEXT LEFT LAST PASSED UNIT ACTIVATES
Sun 2025-08-31 03:00:00 CST 4h 49min left n/a n/a cleanup.timer cleanup.service
总结
通过以上步骤,您已经成功地在 Debian 12 服务器上部署了一个健壮的自动化清理任务。该任务利用一个安全的 Bash 脚本和 systemd 的原生调度功能,无需依赖外部工具(如 cron),即可实现可靠、可追溯的系统维护,有助于长期保持服务器的健康和稳定。