用 xdg-ninja「整治」杂乱的 Linux 家目录
Matrix 首页推荐
Matrix 是少数派的写作社区,我们主张分享真实的产品体验,有实用价值的经验与思考。我们会不定期挑选 Matrix 最优质的文章,展示来自用户的最真实的体验和观点。
文章代表作者个人观点,少数派仅对标题和排版略作修改。
前言
Linux 系统下,大多数软件的配置文件与数据文件都会以隐藏文件的形式存放在用户的家目录之下,并且隐藏文件的文件名都是以英文句号开头的,也就是一个点,所以很多人将这些文件称之为 dotfiles。
在现代化的 Linux 发行版中,理想情况下软件对于 dotfiles 的存放会遵循 XDG 标准,也就是说,软件的配置文件、数据文件、缓存文件等等,会分别存放到 XDG_CONFIG_HOME
、XDG_DATA_HOME
以及 XDG_STATE_HOME
等目录中,在默认情况下,这些目录分别对应为 ~/.config/
、~/.local/share/
和 ~/.cache/
。
但现实情况远没有那么完美,很多软件会将配置文件或数据文件简单粗暴地放在用户的家目录根文件夹里面,导致家目录充满了杂乱无章的文件或文件夹。造成这种情况的原因也很复杂,可能是系统某些环境变量配置有误,又或者是某些软件的历史遗留问题,也可能只是单纯的软件并没有遵循 XDG 规范来进行设计。
对于这种情况,其实也大可以眼不见为净,在文件管理器中关掉显示隐藏文件的选项,大部分时候倒也看不到。不过其中有不少软件是可以通过一些配置让它们的文件放到该去的地方,若你是强迫症就是看这些文件不爽,也不是没有办法。
但是一个个去查找相关软件的配置多少还是有些麻烦了。有没有什么更好的办法来整治这些「违章建筑」呢?答案是肯定的,xdg-ninja 这个项目就是专门用来检查家目录中不合规的文件与文件夹的。
开始安装
xdg-ninja 存在于一部分包管理器的软件仓库中,比如 Nix、AUR 和 Homebrew,软件依赖 jq 和 find 这两个命令行工具,也可以选择安装 glow 来让命令行输出更有可读性。如果 xdg-ninja 没有在你使用的发行版仓库中,因为其本身只是个 bash 脚本,你也可以在安装好相关依赖后直接克隆 GitHub 仓库,然后运行其中的 xdg-ninja.sh
脚本。
在终端中运行 xdg-ninja,就可以看到当前用户家目录中有哪些文件是可以移动的,以及需要做什么配置,这其中可以移动的文件类型与建议配置都是来自于各个软件的相关文档与用户贡献,如果你发现有文件没有检测到,也可以给项目提交规则。
xdg-ninja 并不会自动为你移动家目录中的文件,事实上,它不会修改任何文件,所以不用担心它会搞乱你的家目录。它所做的,就只有读取家目录中的文件名,与仓库中的规则比对,从而显示出哪些文件是可以移动的,之后移动文件与进行配置都需要手动进行。
有点反直觉的是,xdg-ninja 的输出内容中,红色的项目代表的是可以移动的文件,而黄色的项目代表的是不可以移动,或是虽然可以移动,但之后还仍有可能被重新创建的文件。
设置环境变量
xdg-ninja 的输出内容前几行提示我们需要设置 $XDG_DATA_HOME
、XDG_CONFIG_HOME
、XDG_STATE_HOME
与 XDG_CACHE_HOME
这几个环境变量,这是因为我使用的是窗口管理器,很多常用的功能与环境变量默认都没有设置,若你使用的是其他桌面环境且 xdg-ninja 输出中没有这几行的话,就说明这几个环境变量是默认设置好的。
在图形环境下设置环境变量的方法有很多,需要根据自己的实际情况来选择,大多数 Xorg 桌面环境会读取 xprofile 文件,而 Wayland 环境就各不相同了,比如 GDM 登陆管理器和 KDE Plasma 桌面环境默认会从 systemd 读取环境变量,而 SDDM 和 LightDM 则需要在启动脚本里设置环境变量。
我使用的登陆管理器 greetd 默认会从 /etc/profile
和 ~/.profile
文件中读取环境变量,同时在 Archlinux 下 zsh 默认也会读取 /etc/profile
里的环境变量,所以我打算将环境变量放在这里,不过为了方便管理,我将自定义的环境变量放在了 /etc/custom_profiles
里面,然后在 /etc/profile
文件里 source 它。
新建并编辑 /etc/custom_profiles
,在其中添加下面几行:
# XDG directory
export XDG_DATA_HOME=$HOME/.local/share
export XDG_CONFIG_HOME=$HOME/.config
export XDG_STATE_HOME=$HOME/.local/state
export XDG_CACHE_HOME=$HOME/.cache
然后编辑 /etc/profile
文件,在最后添加下面一行:
source /etc/custom_profiles
然后注销重新登录,这些环境变量就会被重新读取了。
一些软件的配置实例
由于家目录中需要处理的文件比较多,篇幅原因我就不把全部的配置过程贴出来了,不过大致方法都差不多,常见的就是修改相关配置文件,或是添加特定的环境变量。另外添加的环境变量需要放在前文设置的几个 XDG 相关的环境变量之后,如果需要全局启用就添加到 /etc/profile
里面,如果只想在终端中启用,就添加到对应的 .zshrc 或 .bashrc 里面。
下面是几个软件的配置实例。
zsh 相关
我的 zsh 配置比较复杂,我使用 zim 来管理插件,还使用了 powerleve10k 主题,除了 ~/.zshrc
,家目录里还有额外的 zsh 相关文件。
首先移动 ~/.zshrc
,按照 xdg-ninja,编辑 /etc/zsh/zshenv
文件,添加下面的环境变量:
export ZDOTDIR="$HOME"/.config/zsh
之后将 ~/.zshrc
移动到 ~/.config/zsh/.zshrc
,因为我使用的 zim 管理插件,还需要将 zim 的配置文件也一并移动到 ~/.config/zsh/.zimrc
,再次打开终端,zim 就会自动下载相关的插件并初始化终端。之后家目录里面的 ~/.zim
文件夹也可以一并删掉了
mkdir ~/.config/zsh
mv ~/.zshrc ~/.config/zsh/.zshrc
mv ~/.zimrc ~/.config/zsh/.zimrc
之后移动 zsh 的历史记录文件,默认 zsh 的历史记录文件会放在和 .zshrc 相同的目录下,xdg-ninja 建议将历史记录文件放在 $XDG_STATE_HOME
里面,在 .zshrc 文件里添加以下环境变量:
export HISTFILE="$XDG_STATE_HOME"/zsh/history
之后将家目录里的历史文件移动过去:
mkdir ~/.local/state/zsh
mv ~/.zhistory ~/.local/state/zsh/history
zim 还会创建 ~/.zcompcache
和 ~/.zcompdump
文件,这是补全插件生成的缓存文件。zim 的命令补全功能是靠内置的插件 completion 实现的,如果按照下面 xdg-ninja 给出的办法设置缓存文件路径会和 zim 冲突产生报错。
按照 zim 的文档,正确的方法是在 .zshrc 文件最前面添加如下两行:
zstyle ':zim:completion' dumpfile ${XDG_CACHE_HOME}/zsh/dumpfile
zstyle ':completion::complete:*' cache-path ${XDG_CACHE_HOME}/zsh/zcompcache
别忘了要手动创建文件夹
mkdir ~/.cache/zsh
还有 powerleve10k 在家目录创建的配置文件 ~/.p10k.zsh
,需要将这个文件移动到 ~/.config/zsh
,然后在 .zshrc 文件里面,找到下面行并修改:
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh
# 改成
[[ ! -f ${ZDOTDIR:-~}/.p10k.zsh ]] || source ${ZDOTDIR:-~}/.p10k.zsh
git
家目录下的 ~/.gitconfig
文件是 git 的配置文件,根据 xdg-ninja,git 目前原生支持 XDG 标准,家目录下的配置文件是旧版本的遗留的文件:
只需将这个文件移动到 $XDG_CONFIG_HOME/git/config
即可。
mkdir ~/.config/git
mv ~/.gitconfig ~/.config/git/config
cargo
cargo 是一个 rust 的包管理器,~/.cargo
文件夹是我在编译安装一些 rust 软件时自动生成的,按照 xdg-ninja,要更改这个目录,需要设置环境变量:
export CARGO_HOME="$XDG_DATA_HOME"/cargo
之后我是直接删掉了这个目录,因为它对我来说并没有什么用。
gnupg
~/.gnupg
文件夹存放的是 gpg 相关的文件,如果有比较重要的密钥文件,则需要加倍小心,根据 xdg-ninja,这个文件夹可以通过设置环境变量修改,但可能会影响一些其他软件,保险起见我还是不动了它吧。
openssh
~/.ssh
文件夹存放着 openssh 相关的文件,包括 ssh 密钥等,目前没办法移动。
Flatpak
~/.var
文件夹是 Flatpak 软件的数据目录,通过 Flatpak 安装的软件是沙盒化的,只可以访问指定的目录,而其余的数据文件都会存放在这个目录中,这个文件夹目前无法移动。
Steam
如果安装了 Steam 的话,家目录中会有好几个 Steam 相关的文件和文件夹,这个问题在 github 上十多年前都有人提出来了,但直到现在都没解决,Valve 似乎并不关心这个问题。目前唯一的解决方案是改用 Flatpak 版本的 Steam。
除了 Steam,还有不少软件在家目录乱放文件且不愿意改,比如 Firefox 会在家目录创建 ~/.mozilla/
文件夹,如果实在看不惯这些文件,可以安装软件的 Flatpak 版本,然后用 Flatseal 来限制它们的文件访问范围和其他权限。需要注意的是要想让 Flatpak 软件遵循全局 GTK 主题,需要一些额外配置,不过这些软件连 XDG 标准都不会遵守,倒也不指望他们能好好地遵循 GTK 主题了😆。
结尾
按照 xdg-ninja 的指引,经过一番配置后,我的家目录是这样的:
除了一些我选择保留的文件,其余文件和文件夹都十分整洁,相比之前杂乱无章的家目录,要赏心悦目不少。
> 关注 少数派小红书,感受精彩数字生活 🍃
> 实用、好用的 正版软件,少数派为你呈现 🚀