强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

systemd 教程 / 临时文件与 tmpfiles.d

临时文件与 tmpfiles.d

概述

tmpfiles.d 是 systemd 提供的临时文件和目录管理机制。通过配置文件,可以声明式地创建、清理和删除临时文件、运行时目录、设备节点等。系统启动时由 systemd-tmpfiles 处理这些配置,也可以通过定时器定期清理过期的临时文件。


配置文件路径

tmpfiles.d 配置文件按优先级从高到低读取(同名文件高优先级覆盖低优先级):

路径说明
/etc/tmpfiles.d/*.conf管理员自定义配置(最高优先级)
/run/tmpfiles.d/*.conf运行时生成的配置
/usr/lib/tmpfiles.d/*.conf软件包安装的默认配置(最低优先级)

文件命名规范

/tmpfiles.d/<优先级>-<名称>.conf

示例:
/tmpfiles.d/10-example.conf
/tmpfiles.d/50-systemd.conf
/tmpfiles.d/99-custom.conf

💡 提示:数字前缀越小优先级越高。自定义配置建议使用 99- 前缀或放在 /etc/tmpfiles.d/ 目录下。

查看已有配置

# 查看所有 tmpfiles.d 配置
ls /usr/lib/tmpfiles.d/
ls /etc/tmpfiles.d/
ls /run/tmpfiles.d/

# 查看特定配置文件内容
cat /usr/lib/tmpfiles.d/systemd.conf

配置文件格式

每行一条规则,格式如下:

Type  Path  Mode  Owner  Group  Age  Argument
字段说明
Type操作类型(创建/删除/清理等)
Path文件或目录的绝对路径
Mode文件权限(八进制)
Owner文件所有者(用户名或 UID)
Group文件所属组(组名或 GID)
Age清理时间阈期(过期时间)
Argument附加参数(取决于 Type)

示例

# 创建运行时目录,权限 0755,所有者 root
d /run/myapp 0755 root root -

# 创建临时目录,7 天后清理
d /tmp/myapp 1777 root root 7d

# 创建符号链接
L /tmp/link - - - - /target/path

# 创建配置文件
f /etc/myapp/config.conf 0644 root root - "default_content"

Type 类型详解

创建类

Type说明特点
f创建文件文件不存在时创建,不覆盖已有内容
f+创建或覆盖文件如果文件存在则截断重写
w写入文件写入内容到已有文件(不创建)
w+写入或创建文件不存在则创建,存在则写入
d创建目录不存在则创建,不清理内容
D创建或清空目录不存在则创建,存在则清空
e创建目录(存在则调整权限)等同于 d,但会调整已有目录权限
v创建目录(subvolume)用于 Btrfs subvolume
q创建目录(不调整已有权限)仅创建,不修改已有目录
Q创建目录(同 q,但忽略挂载点)类似 q
p创建命名管道(FIFO)创建 FIFO 文件
L创建符号链接创建或更新符号链接
c创建字符设备节点创建字符设备文件
b创建块设备节点创建块设备文件

清理类

Type说明配合 Age 使用
r删除文件或目录不使用
R递归删除文件或目录不使用
x排除路径(不删除)不使用
X排除路径(仅排除文件内容)配合 Age
z调整文件权限不使用
Z递归调整文件权限不使用

类型前缀修饰符

前缀说明
-忽略错误(文件不存在等)
!仅在 --boot 模式下执行
!!仅在 --boot 模式下执行且忽略错误
# - 前缀:忽略错误
- /tmp/maybe-exist 0644 root root -

# ! 前缀:仅启动时执行
! /run/boot-time-only 0755 root root -

# !! 前缀:启动时执行,忽略错误
!! /run/optional-boot 0755 root root -

清理策略(Age / TTL)

Age 字段

Age 字段指定文件/目录的最大存活时间,超过后会被清理:

说明
-不自动清理
7d7 天
2h2 小时
30min30 分钟
1w1 周
3month3 个月
1year1 年
1y6month1 年 6 个月

时间单位:

单位说明
s / sec
min分钟
h / hr小时
d / day
w / week
month月(30 天)
y / year年(365 天)

清理规则

清理由 systemd-tmpfiles --clean 执行,通常由定时器自动运行:

# 查看清理定时器
systemctl list-timers systemd-tmpfiles-clean.timer

# 手动执行清理
sudo systemd-tmpfiles --clean

# 仅清理特定配置
sudo systemd-tmpfiles --clean /etc/tmpfiles.d/myapp.conf

目录结构与 Age

对于目录,Age 的计算基于目录中文件的最后访问时间:

# 清理 7 天未访问的文件(但不删除目录本身)
d /tmp/myapp 1777 root root 7d

# 递归清理目录及其内容
e /tmp/myapp 1777 root root 7d

⚠️ 注意d 类型在清理时只删除目录内的过期文件,不删除目录本身。D 类型会在清理时清空整个目录。


systemd-tmpfiles 命令

命令选项

# 创建所有配置中声明的文件和目录
sudo systemd-tmpfiles --create

# 清理过期的临时文件
sudo systemd-tmpfiles --clean

# 删除所有配置中声明的文件和目录
sudo systemd-tmpfiles --remove

# 仅处理特定配置文件
sudo systemd-tmpfiles --create /etc/tmpfiles.d/myapp.conf

# 验证配置文件语法
sudo systemd-tmpfiles --verify

# 显示将要执行的操作(不实际执行)
sudo systemd-tmpfiles --dry-run --create

systemd-tmpfiles-setup 服务

系统启动时自动执行:

# 查看启动时的 tmpfiles 服务
systemctl status systemd-tmpfiles-setup.service
systemctl status systemd-tmpfiles-clean.timer

# 查看日志
journalctl -u systemd-tmpfiles-setup.service

实际案例

案例 1:创建应用运行时目录

# /etc/tmpfiles.d/myapp.conf
# 创建运行时目录
d /run/myapp 0755 myapp myapp -
# 创建 PID 文件目录
d /run/myapp/pid 0755 myapp myapp -
# 创建 socket 目录
d /run/myapp/sock 0755 myapp myapp -
# 应用配置
sudo systemd-tmpfiles --create /etc/tmpfiles.d/myapp.conf

# 验证
ls -la /run/myapp/

案例 2:临时目录自动清理

# /etc/tmpfiles.d/app-temp.conf
# 临时目录,7 天后清理
d /tmp/myapp 1777 root root 7d

# 上传目录,30 天后清理
d /var/tmp/myapp-uploads 0755 www-data www-data 30d

# 缓存目录,14 天后清理
d /var/cache/myapp 0755 myapp myapp 14d

案例 3:权限修复

# /etc/tmpfiles.d/fix-perms.conf
# 确保日志目录权限正确
z /var/log/myapp 0750 myapp myapp -
# 递归修复
Z /var/log/myapp 0640 myapp myapp -
# 执行权限修复
sudo systemd-tmpfiles --create /etc/tmpfiles.d/fix-perms.conf

案例 4:创建符号链接

# /etc/tmpfiles.d/symlinks.conf
# 创建符号链接
L /tmp/current - - - - /opt/myapp/current
L /usr/local/bin/myapp - - - - /opt/myapp/bin/myapp

案例 5:创建 FIFO

# /etc/tmpfiles.d/fifo.conf
# 创建命名管道
p /run/myapp/input 0660 myapp myapp -

案例 6:排除路径

# /etc/tmpfiles.d/cleanup.conf
# 清理 /tmp/myapp,但排除子目录 data
d /tmp/myapp 1777 root root 7d
x /tmp/myapp/data
x /tmp/myapp/data/important

# 清理 /var/tmp,但排除特定目录
D /var/tmp 1777 root root 30d
x /var/tmp/preserved

案例 7:创建设备节点

# /etc/tmpfiles.d/devices.conf
# 创建字符设备
c /dev/mydevice 0660 root dialout 10 200

# 创建块设备
b /dev/myblock 0660 root disk 8 0

tmpfs 挂载

systemd 支持通过 tmpfiles.d 自动挂载 tmpfs:

# /etc/tmpfiles.d/tmpfs.conf
# 挂载 tmpfs
tmpfs /tmp/myapp-tmp tmpfs size=1G,mode=1777 0 0

系统默认 tmpfs 挂载

# 查看系统 tmpfs 挂载点
mount | grep tmpfs

# 常见 tmpfs 挂载点:
# /tmp        — 临时文件
# /dev/shm    — 共享内存
# /run        — 运行时文件

⚠️ 注意/tmp 在许多发行版上默认为 tmpfs,重启后清空。重要临时文件应放在 /var/tmp/


与 tmpwatch/cronie 对比

传统方式:tmpwatch

tmpwatch 是传统的临时文件清理工具:

# 清理 7 天未访问的文件
tmpwatch 7d /tmp

# 清理 30 天未修改的文件
tmpwatch --mtime 30d /var/tmp

对比

对比项tmpfiles.dtmpwatch
管理方式声明式配置命令行参数
功能范围创建 + 清理 + 权限仅清理
集成度systemd 原生独立工具
配置位置/etc/tmpfiles.d//etc/cron.daily/
触发方式systemd 服务 + 定时器cron
设备节点支持不支持
符号链接支持不支持

💡 提示:在 systemd 系统中,推荐使用 tmpfiles.d 替代 tmpwatch,功能更强大且配置更清晰。


调试 tmpfiles.d

验证配置文件

# 验证配置文件语法
sudo systemd-tmpfiles --verify

# 验证特定文件
sudo systemd-tmpfiles --verify /etc/tmpfiles.d/myapp.conf

# 模拟执行(dry-run)
sudo systemd-tmpfiles --dry-run --create /etc/tmpfiles.d/myapp.conf

查看执行日志

# 查看 tmpfiles 服务日志
journalctl -u systemd-tmpfiles-setup.service

# 查看清理定时器日志
journalctl -u systemd-tmpfiles-clean.service

# 实时监控
journalctl -fu systemd-tmpfiles-setup.service

常见问题排查

问题原因解决方案
目录未创建配置文件未被读取检查文件路径和扩展名(必须 .conf
权限不正确Type 使用错误使用 zZ 调整权限
清理不生效Age 设置错误检查时间格式,确保定时器运行
语法规则配置文件格式错误使用 --verify 检查
符号链接失败目标不存在确保目标路径正确

系统默认配置示例

systemd 默认配置

# 查看 systemd 默认 tmpfiles.d 配置
cat /usr/lib/tmpfiles.d/systemd.conf

典型的 systemd.conf 内容:

# /run 目录结构
d /run/lock 0755 root root -
d /run/log 0755 root root -
d /run/user 0755 root root 10d

# /tmp 和 /var/tmp
d /tmp 1777 root root 10d
d /var/tmp 1777 root root 30d

# systemd 相关目录
d /run/systemd 0755 root root -
d /run/systemd/seats 0755 root root -
d /run/systemd/sessions 0755 root root -
d /run/systemd/users 0755 root root -

最佳实践

配置文件组织

# 软件包提供的配置
/usr/lib/tmpfiles.d/mypackage.conf

# 管理员自定义覆盖
/etc/tmpfiles.d/mypackage.conf

# 运行时生成(通常由 systemd 服务生成)
/run/tmpfiles.d/mypackage.conf

命名规范

# 使用数字前缀控制顺序
/etc/tmpfiles.d/10-essential.conf
/etc/tmpfiles.d/50-application.conf
/etc/tmpfiles.d/99-cleanup.conf

权限设置建议

场景权限说明
公共临时目录1777带 sticky bit,用户只能删除自己的文件
应用运行目录0755所有者完全控制,其他只读
敏感数据目录0700仅所有者访问
日志目录0750应用用户和管理组访问

实用命令汇总

# 创建文件和目录
sudo systemd-tmpfiles --create

# 清理过期文件
sudo systemd-tmpfiles --clean

# 删除所有声明的文件
sudo systemd-tmpfiles --remove

# 验证配置
sudo systemd-tmpfiles --verify

# 仅处理特定配置
sudo systemd-tmpfiles --create /etc/tmpfiles.d/myapp.conf

# dry-run 模式
sudo systemd-tmpfiles --dry-run --create

# 查看定时器
systemctl list-timers systemd-tmpfiles-clean.timer

# 查看日志
journalctl -u systemd-tmpfiles-setup.service
journalctl -u systemd-tmpfiles-clean.service

扩展阅读