适用环境

  • 操作系统: Debian 12 (Bookworm)。同样适用于其他基于 systemd 的现代 Linux 发行版,如 Ubuntu 22.04+, CentOS 8+, Rocky Linux 8+。
  • 所需权限: root 或具有 sudo 能力的用户。
  • 前置知识: 熟悉基本的 Linux 命令行操作和文本编辑器(如 nanovim)。

教程目标

本教程将引导您完成以下任务:

  1. 创建一个安全、模块化的 Bash 脚本,用于执行常规的系统清理操作。
  2. 配置一个 systemd Service 单元来运行该脚本。
  3. 配置一个 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),即可实现可靠、可追溯的系统维护,有助于长期保持服务器的健康和稳定。