在 RHEL 7/CentOS 7 中如何自动清理临时文件

我们是否也遇到过这样的情况:文件系统堆满了不需要的文件,而我们必须手动清理所有不需要的临时文件和目录。

在 Red Hat Enterprise Linux 7 中,引入了一个新的 systemd 单元文件 (systemd-tmpfiles),它可以自动为我们完成繁重的工作。

在 RHEL 6 中,我们有一个类似的解决方案,即 tmpwatch,用于清理临时文件,tmpwatch 实用程序递归搜索指定目录并删除在指定时间段内未访问的文件。

systemd-tmpfiles creates, deletes, and cleans up volatile and temporary files and directories, based on the configuration file format and location specified in tmpfiles.d
systemd-tmpfiles 根据 tmpfiles.d 中指定的配置文件格式和位置创建、删除和清理易失性和临时文件和目录

systemd的配置文件位于不同的地方,它们有一个分层的优先级进程。
systemd-tmpfiles 服务的配置位置具有以下顺序优先级(从高到低):

/etc/tmpfiles.d/*.conf
/run/tmpfiles.d/*.conf
/usr/lib/tmpfiles.d/*.conf
  • 假设三个配置目录下都放置了一个同名的配置文件,那么优先级最高的文件就是/etc中的那个。
  • 放置在 /run 下的配置文件由服务/守护程序在运行时创建,以控制临时目录清理过程。
  • 而且,像往常一样,不应直接编辑 /usr/lib/* 下的配置文件,因为它们是供应商提供的,我们应该使用此优先级机制覆盖它们,将自定义文件放在 /etc/tmpfiles.d/* 下。

查看配置文件语法,systemd-tmpfiles 配置包含:

Type, Path, Mode, UID, GID, Age, and Arguments
  • r删除文件或者目录(如果存在)。 这可能不能用于删除非空目录,为此使用 R。 这种类型的行接受 shell 样式的 globs 代替正常的路径名。

例如,我在“/etc/tmpfiles.d”中创建了一个配置文件

# cat tmp.conf
# 删除 /tmp/test 目录和其中内容
r /tmp/test/

在运行之前,我将创建一个目录

# mkdir /tmp/test

让我们手动运行 systemd-tmpfiles 来检查它是否有效

# env SYSTEMD_LOG_LEVEL=debug systemd-tmpfiles --remove
Skipping overridden file: /usr/lib/tmpfiles.d/tmp.conf.
Reading config file "/etc/tmpfiles.d/tmp.conf".
Running remove action for entry r /tmp/test

'test' 目录被删除

# ls /tmp/test
ls: cannot access /tmp/test: No such file or directory

但是如果目录有一些内容怎么办

# env SYSTEMD_LOG_LEVEL=debug systemd-tmpfiles --remove
Skipping overridden file: /usr/lib/tmpfiles.d/tmp.conf.
Reading config file "/etc/tmpfiles.d/tmp.conf".
Running remove action for entry r /tmp/test
rm(/tmp/test): Directory not empty

对于这种情况,我们需要不同的变量

  • R递归删除路径及其所有子目录(如果它是目录)。 这种类型的行接受 shell 样式的 globs 代替正常的路径名。

看起来它能起作用:

# env SYSTEMD_LOG_LEVEL=debug systemd-tmpfiles --remove
Skipping overridden file: /usr/lib/tmpfiles.d/tmp.conf.
Reading config file "/etc/tmpfiles.d/tmp.conf".
Running remove action for entry R /tmp/test
rm -rf "/tmp/test"

什么时候进行自动清理?

Systemd 为我们提供了用于控制在运行系统中执行的计划和循环操作的计时器单元。

我们可以通过查询 systemd 守护进程来检查计时器单元的行为

# systemctl status systemd-tmpfiles-clean.timer
â systemd-tmpfiles-clean.timer - Daily Cleanup of Temporary Directories
   Loaded: loaded (/usr/lib/systemd/system/systemd-tmpfiles-clean.timer; static; vendor preset: disabled)
   Active: active (waiting) since Sat 2015-01-20 23:55:24 IST; 15h ago
     Docs: man:tmpfiles.d(5)
           man:systemd-tmpfiles(8)
Jan 20 23:55:24 Ban17-rds01-b systemd[1]: Started Daily Cleanup of Temporary Directories.
Jan 20 23:55:24 Ban17-rds01-b systemd[1]: Starting Daily Cleanup of Temporary Directories.

如果我们检查此服务的 systemd 单元文件,它将为我们提供更多详细信息

# systemctl cat systemd-tmpfiles-clean.timer
# /usr/lib/systemd/system/systemd-tmpfiles-clean.timer
#  This file is part of systemd.
##  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.
[Unit]
Description=Daily Cleanup of Temporary Directories
Documentation=man:tmpfiles.d(5) man:systemd-tmpfiles(8)
[Timer]
OnBootSec=15min
OnUnitActiveSec=1d

正如我们将在计时器单元上发现的那样,它会在 systemd 启动后仅运行 15 分钟,然后从那时起每 24 小时运行一次。
在这种情况下,该命令只会影响文件/目录的清除/清理。

一旦系统启动,就会执行一个特殊的单元文件:systemd-tmpfiles-setup,这个单元会执行systemd-tmpfile --create --remove命令。

我会在/tmp下再次创建一个test目录,并创建一个配置文件来清除这个目录,

# cat /etc/tmpfiles.d/tmp.conf
# Remove /tmp/test directory and its content
r /tmp/test/

接下来重新启动我的系统以验证更改

# reboot

接下来监控日志

Jan 20 16:44:24 Ban17-adm-a systemd: Stopped Daily Cleanup of Temporary Directories.
Jan 20 16:44:24 Ban17-adm-a systemd: Stopping Daily Cleanup of Temporary Directories.

在启动系统时

Jan 20 16:49:14 Ban17-adm-a systemd: Started Daily Cleanup of Temporary Directories.
Jan 20 16:49:14 Ban17-adm-a systemd: Starting Daily Cleanup of Temporary Directories.

一旦系统可以再次访问,让我们检查“/tmp/test”是否存在

# ls /tmp/test
ls: cannot access /tmp/test: No such file or directory

可以看到其已被自动清理。

日期:2020-06-02 22:18:25 来源:oir作者:oir