XDG(X Desktop Group,现为 freedesktop.org)规范族定义了 Linux/Unix 桌面应用”配置文件放哪、缓存放哪、应用如何注册”的互操作约定。其中最常被引用的核心是 XDG Base Directory Specification(当前版本 0.8,2021-05-08),它解决的是”每个应用都在 $HOME 下建一个 .appname 目录,把家目录搞成垃圾场”的问题。
为什么需要它
没有 XDG 时,应用各自决定落盘位置,导致:
$HOME根目录被~/.app1 ~/.app2 ~/.app3淹没,无法区分哪些能删- 配置、用户数据、缓存、运行时文件混在一起,备份和清理无从下手
- 无法整体重定向(比如把缓存移到另一块盘)
XDG 用”按用途分层 + 环境变量可覆盖 + 系统目录可回退”三招把落盘位置标准化。
规范族一览
XDG 不是单一规范,而是一组 freedesktop.org 规范。日常说的”XDG 规范”多指前两个:
| 规范 | 作用 | 代表环境变量/文件 |
|---|---|---|
| basedir(v0.8) | 配置/数据/缓存/状态/运行时目录的落盘约定 | XDG_CONFIG_HOME 等 |
| xdg-user-dirs | ”文档/下载/图片”等用户可见目录的本地化与重定向 | ~/.config/user-dirs.dirs |
| desktop-entry(v1.5) | .desktop 文件格式:应用如何启动、如何显示在菜单 | applications/*.desktop |
| autostart(v0.5) | 登录时自启动的 .desktop 约定 | ~/.config/autostart/ |
| mime-apps(v1.0.1) | 文件类型到默认应用的映射 | mimeapps.list |
| shared-mime-info | MIME 类型数据库 | ~/.local/share/mime/ |
| icon-theme / icon-naming | 图标主题与命名 | ~/.local/share/icons/ |
| trash(v1.0) | 回收站格式与位置 | ~/.local/share/Trash/ |
| recent-files / notification / clipboard | 最近文件、通知、剪贴板协议 | — |
注:
xdg-desktop-portal常和 XDG 一起出现,但它不在上述规范列表中,是独立的 portal 项目,用于沙箱应用访问文件选择器、截图等宿主能力。
Base Directory 核心:八个环境变量
规范定义了 6 个”可覆盖的基础目录”变量(单值)+ 若干约定:
| 环境变量 | 用途 | 未设置/为空时的默认值 | 值类型 |
|---|---|---|---|
XDG_DATA_HOME | 用户专属数据文件(可持久、重要) | $HOME/.local/share | 单路径 |
XDG_CONFIG_HOME | 用户专属配置文件 | $HOME/.config | 单路径 |
XDG_STATE_HOME | 应用重启后仍需保留、但不适合放 data 的状态 | $HOME/.local/state | 单路径 |
XDG_CACHE_HOME | 非必要的缓存数据,可随时删 | $HOME/.cache | 单路径 |
XDG_DATA_DIRS | 数据文件的系统级搜索路径(附加在 DATA_HOME 之后) | /usr/local/share/:/usr/share/ | 多路径(冒号分隔) |
XDG_CONFIG_DIRS | 配置文件的系统级搜索路径(附加在 CONFIG_HOME 之后) | /etc/xdg | 多路径(冒号分隔) |
XDG_RUNTIME_DIR | 运行时文件(socket、命名管道),登录期有效 | 无默认值 | 单路径 |
| (无变量) | 用户级可执行文件 | $HOME/.local/bin | 约定 |
XDG_STATE_HOME 是 v0.8 新增的,典型内容是:操作历史、最近使用文件、可恢复的界面布局/打开文件/撤销历史。判定口径是 —— 删除它不会丢用户数据(不是 data),但删了会丢使用体验(比 cache 重要)。
关键规则
- 必须是绝对路径:环境变量里出现相对路径,实现应视为非法并忽略。
- 空值等于未设置:
XDG_CONFIG_HOME=""与不设置等价,都要回退到默认值。 - 优先级顺序 = 排列顺序:
XDG_DATA_HOME优先于所有XDG_DATA_DIRS;XDG_CONFIG_HOME优先于所有XDG_CONFIG_DIRS;多路径列表里越靠前越重要,同名信息以第一个为准。 - 多路径用
$PATH分隔符:通常是:(Windows 上是;)。单个条目为空(如/a::/b)在不同实现里行为有差异,实践中应避免。 - 写入时自动建目录、权限 0700:目标目录不存在时应尝试以
0700创建;若已存在则不得修改其权限;创建/写入失败要能优雅报错。 - 读取时跳过不可用项:目录不存在、文件不存在、无权限等都应跳过继续查找,而不是直接失败。
XDG_RUNTIME_DIR 的特殊性
它不是普通目录,约束比其它几个严格得多:
- 必须归当前用户所有,且只有该用户能读写,Unix 权限必须是
0700 - 生命周期绑定登录会话:首次登录创建、完全登出删除;多次登录指向同一目录
- 文件不得跨重启/完整登出登录存活
- 必须位于本地文件系统、不可跨主机共享
- 需完整支持 socket、符号链接、硬链接、文件锁、mmap、inotify 等能力
- 可能被定期清理;若要保活,需每 6 小时内更新 atime,或设置 sticky bit
- 未设置时应用应回退到能力相近的目录并打印警告
典型值形如 /run/user/1000,由 PAM/systemd-logind 在登录时创建。
典型目录布局
$HOME/
├── .config/ # XDG_CONFIG_HOME 配置,备份对象
│ ├── nvim/
│ ├── user-dirs.dirs # 用户目录定义
│ └── autostart/
├── .local/ # 用户级 "prefix",类似 /usr 的用户版
│ ├── bin/ # 用户可执行文件(需在 PATH 中)
│ ├── share/ # XDG_DATA_HOME 持久数据
│ │ ├── applications/ # .desktop 用户条目
│ │ ├── fonts/
│ │ └── Trash/
│ └── state/ # XDG_STATE_HOME 历史/会话状态
├── .cache/ # XDG_CACHE_HOME 可随时删
└── .ssh/ 等 # 各工具自己的历史遗留目录,非 XDG
/run/user/<uid>/ # XDG_RUNTIME_DIR 登录期有效
/etc/xdg/ # XDG_CONFIG_DIRS 系统级配置
/usr/share/ # XDG_DATA_DIRS 系统级数据
对照记忆:~/.config ≈ /etc,~/.local/share ≈ /usr/share,~/.cache ≈ /var/cache,~/.local/state ≈ /var/lib。
用户目录(xdg-user-dirs)
~/.config/user-dirs.dirs 用 shell 可 source 的格式定义”文档/下载/图片”等用户可见目录:
XDG_DESKTOP_DIR="$HOME/Desktop"
XDG_DOWNLOAD_DIR="$HOME/Downloads"
XDG_TEMPLATES_DIR="$HOME/Templates"
XDG_PUBLICSHARE_DIR="$HOME/Public"
XDG_DOCUMENTS_DIR="$HOME/Documents"
XDG_MUSIC_DIR="$HOME/Music"
XDG_PICTURES_DIR="$HOME/Pictures"
XDG_VIDEOS_DIR="$HOME/Videos"- 值必须是
"$HOME/Path"或"/Path"形式;指向$HOME表示禁用该目录 - 默认值来自
${XDG_CONFIG_DIRS}/user-dirs.defaults(通常是/etc/xdg/user-dirs.defaults),按 locale 翻译目录名 - 开机早期由
xdg-user-dirs-update生成/更新;删除该文件会在下次登录被重建 - 应用读取方式(shell):
test -f "${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs" && \
. "${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs"
echo "${XDG_DOCUMENTS_DIR:-$HOME}"桌面入口与关联(简述)
.desktop文件放在$XDG_DATA_HOME/applications(用户)与$XDG_DATA_DIRS/applications(系统),同名以用户目录优先- 文件是 INI 风格:
[Desktop Entry]+Type/Name/Exec/Icon/Categories等键;Exec的%f/%u/%U等字段码表示传入文件或 URL - MIME 关联写在
mimeapps.list的[Default Applications]/[Added Associations]/[Removed Associations]段 - 自启动约定放在
$XDG_CONFIG_HOME/autostart与$XDG_CONFIG_DIRS/autostart
落地与工具
写应用时应通过库解析,而不是硬编码 ~/.appname:
| 生态 | 工具 |
|---|---|
| shell | xdg-utils:xdg-open / xdg-mime / xdg-user-dir / xdg-settings |
| Python | platformdirs(推荐)、click.get_app_dir、appdirs(旧) |
| Go | os.UserConfigDir / os.UserCacheDir,或 adrg/xdg |
| Rust | directories / dirs crate |
| Node.js | env-paths |
| 系统配置 | Nix Home Manager 的 xdg.* 模块可声明式管理 |
常见坑
- 硬编码
~/.appname:最常见的违规写法,用户无法通过环境变量重定向。 - 把缓存写进 config/data:缓存应进
XDG_CACHE_HOME,否则备份被垃圾撑爆。 - 多路径顺序搞反:
XDG_CONFIG_DIRS是”越靠前越优先”,不是覆盖式合并;引用该规范的子规范需自己定义冲突时的取舍规则。 - 相对路径被静默忽略:设了
XDG_CONFIG_HOME=config会被规范判定非法而回退默认值,排查时容易误判。 - macOS 上不生效:XDG 是 Linux/Unix 桌面标准,macOS GUI 应用走
~/Library/*;只有部分 CLI 工具会主动兼容 XDG(可用platformdirs统一两者)。 XDG_RUNTIME_DIR被当持久目录用:其中文件登出即删,不能存跨会话数据。
相关
- zsh-startup-optimization — shell 启动优化,XDG 目录影响配置探测顺序
- tools-config-files — Python 项目配置文件约定,可对照应用级 XDG 配置目录
- 07-environment-variables — 环境变量在桌面应用运行时的行为
- application-octet-stream — MIME 类型体系,与 XDG 的 MIME 关联规范互补