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-infoMIME 类型数据库~/.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:

生态工具
shellxdg-utils:xdg-open / xdg-mime / xdg-user-dir / xdg-settings
Pythonplatformdirs(推荐)、click.get_app_dir、appdirs(旧)
Goos.UserConfigDir / os.UserCacheDir,或 adrg/xdg
Rustdirectories / dirs crate
Node.jsenv-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 被当持久目录用:其中文件登出即删,不能存跨会话数据。

相关