服务器运行一段时间后,/tmp 和 /var/tmp 等目录往往会堆积大量过期文件,占用 inode 和磁盘空间,甚至影响系统性能。手动清理不仅低效,还容易遗漏。最可靠的做法是借助 Cron 定时任务,让系统自动清理不再需要的临时文件。下面直接进入具体配置和实战方法。

理解临时文件清理的目标目录

在 Ubuntu 系统中,临时文件主要分布在几个关键位置。最常见的是 /tmp,这个目录在系统重启时通常会被清空,但服务器往往长期不重启,文件就会持续累积。另一个是 /var/tmp,这里的文件在重启后会被保留,更容易成为清理死角。用户家目录下的 .cache 文件夹也容易膨胀,里面存放着各类应用程序的缓存数据。此外,特定服务如 PHP 的 session 文件、系统日志的轮转残留、软件包管理器的下载缓存等,都是需要定期清理的对象。清理之前,务必确认这些目录下哪些文件可以安全删除,避免误删正在被进程使用的临时锁文件或 socket 文件。

编写安全的清理脚本

直接用 Cron 执行 rm 命令风险较大,建议将清理逻辑写入独立的 Shell 脚本,便于维护和测试。脚本的核心思路是使用 find 命令查找符合时间条件的文件并删除。以下是一个典型的清理脚本示例:

#!/bin/bash
# 清理脚本:/usr/local/bin/clean-tmp.sh

# 清理 /tmp 下超过 7 天未访问的文件
find /tmp -type f -atime +7 -delete 2>/dev/null

# 清理 /var/tmp 下超过 14 天未修改的文件
find /var/tmp -type f -mtime +14 -delete 2>/dev/null

# 清理用户缓存中超过 30 天的文件
find /home/*/.cache -type f -atime +30 -delete 2>/dev/null

# 清理 PHP session 文件(超过 1 天未修改)
if [ -d /var/lib/php/sessions ]; then
    find /var/lib/php/sessions -type f -mtime +1 -delete 2>/dev/null
fi

# 清理 systemd 日志轮转后残留的临时文件
journalctl --vacuum-time=7d 2>/dev/null

# 清理 apt 下载缓存(仅保留最新版本)
apt-get clean 2>/dev/null

脚本中的 -atime 和 -mtime 分别代表访问时间和修改时间,单位是天。使用 -delete 参数比通过管道传递给 xargs 更高效安全。2>/dev/null 用于抑制权限不足等错误提示。脚本编写完成后,务必赋予执行权限:chmod +x /usr/local/bin/clean-tmp.sh。

配置 Cron 定时任务

Cron 是 Ubuntu 内置的任务调度器,配置方式分为系统级和用户级两种。系统级 Cron 通过编辑 /etc/crontab 或向 /etc/cron.d/ 目录添加文件实现,可以指定以哪个用户身份运行脚本。用户级 Cron 则通过 crontab -e 命令编辑,任务以当前用户权限执行。对于临时文件清理,通常使用 root 权限的系统级 Cron,因为部分目录普通用户无权操作。推荐在 /etc/cron.d/clean-tmp 中创建专用配置文件:

# 每天凌晨 3 点执行临时文件清理
0 3 * * * root /usr/local/bin/clean-tmp.sh >> /var/log/clean-tmp.log 2>&1

这条配置的含义是每天凌晨 3 点以 root 身份运行清理脚本,并将输出和错误信息追加到日志文件。Cron 时间表达式从左到右依次是分、时、日、月、星期,* 代表任意值。如果服务器在夜间负载较低,凌晨执行是理想选择;如果业务有低峰时段,可根据实际情况调整。

使用 tmpfiles.d 作为补充方案

Ubuntu 使用 systemd 后,引入了 tmpfiles.d 机制来管理临时文件和目录。相比 Cron 脚本,tmpfiles.d 更贴近系统底层,在系统启动时和运行期间都能发挥作用。配置文件位于 /etc/tmpfiles.d/、/run/tmpfiles.d/ 和 /usr/lib/tmpfiles.d/,优先级依次递减。创建一个自定义配置文件 /etc/tmpfiles.d/clean-custom.conf:

# 清理 /tmp 下超过 1 天的文件
d /tmp 1777 root root 1d

# 清理 /var/tmp 下超过 7 天的文件
d /var/tmp 1777 root root 7d

# 自动创建并清理应用临时目录
d /var/run/myapp 0755 myuser mygroup 3d

配置行的格式为:类型、路径、权限、属主、属组、清理时间。类型 d 代表目录,会在系统启动时创建不存在的目录,并按指定时间清理。时间单位可以是 s(秒)、m(分)、h(时)、d(天)、w(周)。配置完成后,执行 systemd-tmpfiles --clean /etc/tmpfiles.d/clean-custom.conf 可以手动触发清理,验证配置是否生效。tmpfiles.d 的优势在于不依赖 Cron 服务,且清理逻辑由 systemd 统一管理,适合对可靠性要求较高的场景。

设置安全的清理策略

清理临时文件不能一味追求彻底,需要平衡磁盘空间和系统稳定性。对于 /tmp 目录,7 天是一个比较安全的阈值,既能释放空间,又不会影响长时间运行的进程。如果服务器上运行着数据库或消息队列,它们的 socket 文件和 PID 文件通常也放在 /tmp 下,这些文件虽然修改时间较早,但进程仍在使用。find 命令的 -delete 操作不会删除正在被进程占用的文件,因为文件被打开时 inode 不会立即释放,但目录项会被移除,可能导致新进程找不到 socket 文件。更稳妥的做法是结合 fuser 或 lsof 检查文件是否被占用,但会显著增加脚本复杂度。实际运维中,多数场景下直接使用 find -delete 已经足够安全,只要确保清理时间阈值不要设置得过短。

监控和验证清理效果

Cron 任务配置完成后,需要持续监控其执行情况。首先检查日志文件 /var/log/clean-tmp.log,确认脚本正常执行且没有异常错误。其次定期查看磁盘使用率:df -h 和 du -sh /tmp /var/tmp,观察清理前后的空间变化。还可以在脚本中添加磁盘使用率记录,便于长期追踪:

echo "$(date): Before cleanup" >> /var/log/clean-tmp.log
df -h /tmp /var/tmp >> /var/log/clean-tmp.log
# 清理命令...
echo "$(date): After cleanup" >> /var/log/clean-tmp.log
df -h /tmp /var/tmp >> /var/log/clean-tmp.log

如果 Cron 任务没有按预期执行,常见原因包括:脚本没有执行权限、Cron 配置文件语法错误、环境变量缺失导致命令找不到。Cron 执行时的环境变量非常精简,脚本中应使用绝对路径,或在脚本开头显式设置 PATH 变量。通过 grep CRON /var/log/syslog 可以查看 Cron 服务的运行日志,定位任务是否被调度。

进阶技巧与常见陷阱

对于多用户服务器,不同用户的家目录缓存需要分别清理。可以在脚本中遍历 /home 下的用户目录,但要注意跳过服务账户和系统账户。使用 find 命令时,-atime 和 -mtime 的时间计算方式是 24 小时为一个单位,而非自然日,这一点在设置阈值时需要留意。如果服务器使用 SSD 存储,频繁的大量文件删除可能触发写入放大效应,建议将清理频率设置为每天一次即可,避免过于频繁。对于需要保留的特定临时文件,可以在 find 命令中使用 ! -name 参数排除,或使用 -regex 进行更灵活的匹配。另外,如果服务器内存充裕,可以考虑将 /tmp 挂载为 tmpfs 文件系统,这样重启后自动清空,结合 Cron 清理运行期间累积的文件,双重保障。

与其他系统工具的配合

Ubuntu 自带的 unattended-upgrades 工具可以自动安装安全更新,更新过程中会产生临时文件。将清理脚本的执行时间设置在自动更新完成之后,可以及时回收更新产生的临时文件。logrotate 负责日志轮转,但轮转后的旧日志如果长时间不删除也会占用空间,可以在清理脚本中加入对 /var/log 下压缩日志的清理逻辑。如果使用了 Docker 等容器技术,容器产生的临时文件、悬空镜像和停止的容器也会消耗大量磁盘空间,定期执行 docker system prune -f 也应纳入清理计划。

总结操作清单

梳理一下完整的配置流程:创建清理脚本并测试,赋予执行权限;编辑系统级 Cron 配置文件,设置合适的执行时间;配置日志记录,便于后续审计;可选地创建 tmpfiles.d 规则作为补充;监控执行日志和磁盘使用率;根据实际运行情况调整清理阈值和频率。这套方案在 Ubuntu 18.04、20.04、22.04 及 24.04 等主流版本上均适用,无需额外安装软件,完全基于系统自带工具实现。