前言
本人在生活中就是一个秩序敏感者,喜欢将桌面整理的井井有条,很享受简洁给我带来的安定感。
这种习惯也带入到使用电脑的场景,我所有文档都分类摆放在特定目录,在任何时候我都可以快速准确到找到需要的文件。
也会定期清理不重要的文件,让资源管理器处于轻松
的状态。这算一种强迫症,喜欢删除认为不重要的东西,也反感应用软件在我非预期的地方放置文件。
电影《机器人总动员》里面有个扫地机器人,它非常热衷于自己的清洁工作,容忍不了一点点污染,是我印象深刻的片段。
$HOME 目录
在桌面操作系统中会为每个用户分配一个「用户目录」,当前用户在使用系统时产生的数据都会保存在这个用户目录下。
系统也会预设好一些通用分类的目录如:
- 图片
- 文稿
- 下载
- 音乐
- 应用程序
- 影片
- 桌面
我们在管理数字资产的时候通常会遵循预设的分类去摆放数据,以便我们的管理和检索。
一些应用程序在使用期间会产生一些配置文件,缓存文件和用户数据等。
用户目录已经有一些较为通用的分类文件夹如: .cache
、.config
、.local
往往很多应用程序都是将这些数据直接放置在用户的根目录,并创建自己的专属文件夹(.xxx),如图:

理论上类似 .npm
、 .vscode
这些目录都是应该收敛到 .cache
、.config
、.local
去的。
强迫症患者 + 洁癖患者看着这么多的 .xxx 文件夹确实是非常难受!!
到处拉屎的 .zsh
Oh My ZSH 对于程序员来说应该无需赘述,它非常优秀,是我愿意使用终端必要前提。但是它有个缺点,就是会在你的用户目录下生成很多意外
文件。
比如在成功安装好 Oh My ZSH 之后,我预期的文件只有
- $HOME/.oh-my-zsh
- $HOME/.zshrc
但是事实是在我的用户目录下会额外生成如下文件:
- .zprofile
- .zsh_history // 输入历史
- .zsh_sessions // 会话历史
- .zcompdump // 加速自动补全
- .zcompdump.zwc // 编译版本,进一步加速自动补全
是的,它就是这么随意。
强迫症的我每次看到这些不速之客都非常难受,因为它们都有自己的作用,且哪怕删除了下次启动又会自动生成。

于是就开始折腾如何收敛这些文件,好在可以在 .zshrc 中通过复写这些路径的变量,来达到收敛的目的。
export NODE_REPL_HISTORY="" # 关闭在终端中使用 node 的输入历史记录
export LESSHISTFILE=- # 关闭使用 less 命令的记录
# 在公共的缓存目录创建 oh-my-zsh 的缓存目录
export ZSH_CACHE_DIR="$HOME/.cache/oh-my-zsh"
mkdir -p $ZSH_CACHE_DIR
# 设置 zsh dump 的缓存文件
export ZSH_COMPDUMP="$ZSH_CACHE_DIR/.zcompdump"
# 设置 zsh 的历史记录文件
export HISTFILE="$ZSH_CACHE_DIR/.zsh_history"
# 设置 zsh 的 session 文件
# 当前设置无效,需要在 /private/etc/zshrc_Apple_Terminal 中设置
export SHELL_SESSION_DIR="$ZSH_CACHE_DIR/.zsh_sessions"
mkdir -p $SHELL_SESSION_DIR
这样就可以把那些临时文件都收敛到 $HOME/.cache
中,眼不见为净。
意外的发现
当我整理完 oh-my-zsh 的临时文件时,接着扫视 $HOME
,发现一个 .gk
的文件夹有点碍眼。
如何评判是否碍眼
?
就是我觉得它不是常规软件生成的,只是个妃子,不配在 $HOME
拥有独立位置的文件。
比如我会觉得 .npmrc
和 .ssh
这种咖位的配置,直接存在于 $HOME
是更容易接受的。(是的,是个严重的双标党)
于是开始谷歌这个 .gk
是干嘛的,搜到对应的 vscode-gitlens-issue 有人同样反感这个文件在 $HOME
里生成,建议作者采纳修改建议。

作者表示不想改,并且巴拉巴拉...
接着该用户搬出了一个社区的规范,并且列举了一些已经遵守该规范的 PR

于是我就发现了 XDG_Base_Directory 这个造福强迫症患者对人类文明进步做出贡献的规范。
XDG_Base_Directory
XDG_Base_Directory (Cross-Desktop Group)是一个由 freedesktop 发起的标准规范。 定义了配置文件
、数据文件
、状态数据
和缓存文件
的存储路径,主要用于类 Unix/Linux 系统。
这套标准的目标是 减少 $HOME
目录的混乱,避免一堆 .*
文件(如 .bashrc
、.gitconfig
、.zsh_history
)直接放置在 $HOME
里。
XDG 规范主要定义了以下 4 个环境变量:
变量 | 作用 | 适合存放的数据 | 示例 |
---|---|---|---|
XDG_CONFIG_HOME | 配置文件 | 用户的应用配置 | ~/.config/git/config |
XDG_CACHE_HOME | 缓存 | 可随时删除的数据 | ~/.cache/zsh/ |
XDG_DATA_HOME | 用户数据 | 需要长期存储的数据 | ~/.local/share/nvim/undo/ |
XDG_STATE_HOME | 应用状态数据 | 运行时状态、日志、历史记录 | ~/.local/state/zsh/history |
所以正常情况下我们都需要在 .zshrc 里做如下配置:
# XDG Base Directory Specification https://wiki.archlinux.org/title/XDG_Base_Directory
export XDG_CONFIG_HOME="$HOME/.config"
export XDG_CACHE_HOME="$HOME/.cache"
export XDG_DATA_HOME="$HOME/.local/share"
export XDG_STATE_HOME="$HOME/.local/state"
# XDG Base Directory Specification end
如果应用程序跟进实现了此标准,那么在需要保存文件的时候,会优先读取 XDG-
对应的路径(用户自定义),否则回退到系统默认。
正常情况下都推荐将 XDG-
对应的路径设置为系统默认,即如上给出的配置示例。除非你有特别强烈的定制需求。
比如某个应用程序需要往磁盘写入一些缓存文件,那么应该按照如下方式实现:
import { join } from 'path';
import { homedir } from 'os';
const XDG_CACHE_HOME = process.env.XDG_CACHE_HOME || join(homedir(), ".cache");
const applicationCachePath = join(XDG_CACHE_HOME, 'your-application-name')
虽然推荐应用按如上示例的优先级去获取路径,但是有些应用为了保持用户的习惯,在获取不到 process.env.XDG_CACHE_HOME
时,它是默认回退到 ~/.xxx
。
比如 Git
$GIT_CONFIG_GLOBAL
(如果设置了)$HOME/.gitconfig
/etc/gitconfig
(系统级别)
所以为了确保实现了 XDG_Base_Directory 规范的应用优先获取到 XDG-
路径,推荐用户都明确做好如下配置,确保命中第一优先级。
# XDG Base Directory Specification https://wiki.archlinux.org/title/XDG_Base_Directory
export XDG_CONFIG_HOME="$HOME/.config"
export XDG_CACHE_HOME="$HOME/.cache"
export XDG_DATA_HOME="$HOME/.local/share"
export XDG_STATE_HOME="$HOME/.local/state"
# XDG Base Directory Specification end
XDG_Base_Directory 维护了一个表格,将那些已经遵循该规范的应用列举在上面。
我截取了部分,有兴趣的同学可以点击链接 进行查看。
Application | Legacy Path | Supported Since | Discussion | Notes |
---|---|---|---|---|
act | ~/.actrc | [5] |
If present | |
aerc | fff1664 | XDG_CONFIG_HOME/aerc/aerc.conf | ||
ALSA | ~/.asoundrc | [6] | XDG_CONFIG_HOME/alsa/asoundrc | |
anacondaAUR | ~/.conda/.condarc , ~/.conda/condarc , ~/.conda/condarc.d/ , ~/.condarc | 4.11.0 | [7] [8] | |
Android Studio | ~/.AndroidStudioX.X | Android Studio 4.1 |
Location overview by Google does not mention XDG - paths could be hardcoded instead of using the proper variable, though that is unlikely as Intellij IDEA, which Android Studio is based on, implements it properly as well | |
Anki | ~/Anki , ~/Documents/Anki | [9] [10] [11] | Uses $XDG_DATA_HOME/Anki2 as default if no older location exists, can be changed by using anki -b <anki_dir> | |
antimicrox | ~/.antimicro , ~/.antimicrox | edba864 | [12] | |
apvlvAUR | ~/.apvlvrc | [13] | [14] | Uses XDG_CONFIG_HOME/apvlv/apvlvrc now if it exist. |
它甚至列举了这些应用从哪个版本开始遵循该标准,且给出了具体的修改PR。
下面简单看个 PR

咱们前端的包管理工具 pnpm 也跟进了此规范 具体查看
实际效果:

xdg-ninja

GitHub 上的一个小工具,用于检测当前用户目录是否有可迁移到 XDG 目录的文件。

遵循标准的收益
如果所有软件都自觉遵守该规范,那么 $HOME
将会变得非常干净,也更便于文件管理。
清理数据
当你想清理磁盘,可以大胆的删除 $XDG_CACHE_HOME
or $HOME/.cache
这样所有应用程序产生的缓存文件就全部被删除了。
加速检索
可以把 $XDG_CACHE_HOME
or $HOME/.cache
这类文件加入忽略列表,可以提升检索效率。
数据迁移
如果要重装系统,那么你可以直接备份 $XDG_CONFIG_HOME
到新系统。这样你之前苦心经营好的软件配置都全部同步好了。
结尾
在 2025 年期待一下:
所有应用产生的文件都在它该有的地方,所有应用在卸载的时候都可以将自己创建的非用户数据
一并删除。
希望在若干年后,我们可以拥有一个简洁规范的 $HOME
目录。
这个世界的美好,离不开那些为之努力的人,哪怕是在某个极小慎微的地方做付出。他们在默默推动标准的实现,我列举一些在搜索资料时看到的案例:
有热心用户给出优化建议,有负责任的开发者积极采纳。
立个 FLAG 吧,我目前负责公司的某个产品的客户端开发,我后期也会推进这个规范的落地。
友情提示
如果看文章的你在点击这些外链会看到这个页面:

那么你可以安装我的另外一个浏览器插件 「redirect-skipper」它可以让你无感跳过这些中转页面。