当你在命令行或终端输入一个命令时,操作系统会在 PATH 环境变量中列出的每个目录中搜索相应的可执行文件。如果 PATH 环境变量包含大量不必要的目录,系统就需要花费更多的时间来搜索,这会降低命令的执行速度,尤其是在执行一些常用命令时,这种影响会更加明显。精简 PATH 可以减少搜索范围,从而加快命令的查找速度。过长的 PATH 环境变量会占用更多的内存和系统资源。虽然这种占用通常不大,但在资源有限的系统上(如嵌入式设备或老旧电脑),精简 PATH 仍然可以带来一定的性能提升。
PATH 环境变量由 shell 或 libc 读取,用于查找和执行程序。这就是当在终端输入 ls
时,shell 能找到 /bin/ls
的原因。
精简 PATH 变量
在基于 Debian 的桌面系统上,默认的 PATH 变量如下所示:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
但很多路径其实并不必要。
-
现代系统的目录简化
在现代系统中,/{bin,sbin}/
目录已经是/usr/{bin,sbin}/
的符号链接。 -
移除
/usr/local
/usr/local
对我来说没有用。如果我需要编译或安装软件,我更倾向于将它们放在默认位置。如果忘记在编译时使用./configure --prefix=/usr
,我已将/usr/local
设置为链接到/usr
(cd /usr && ln -s /usr local
)。对于不在公共仓库中的守护进程类软件,我会放在/opt
。
这样,PATH 变量可以简化为:
PATH=/usr/sbin:/usr/bin:/usr/games
- 进一步优化
我还移除了/usr/games
,因为我通过 GUI 启动游戏(如.desktop
文件)。这些.desktop
文件位于${XDG_DATA_DIRS}/applications
。
到 2024 年,我最终使用了根目录的符号链接,将 PATH 变量进一步简化:
PATH=/sbin:/bin
未来,/usr/sbin
可能会合并到 /usr/bin
,到那时只需要 /bin
就足够了。
扩展 PATH 变量
在 /etc/environment
中设置 PATH 并不能覆盖全部情况。
一旦 shell 被加载,它还会读取 /etc/profile
和 ~/.profile
。
现代编程环境的调整
像 Rust 或 Python 这样的现代编程环境通常会在 PATH 中添加自己的条目。但我更倾向于手动管理 PATH,因此我会创建符号链接:
$ file ~/bin ~/bin-rust ~/bin-py ~/bin-go ~/bin-js
~/bin: directory
~/bin-rust: symbolic link to .cargo/bin
~/bin-py: symbolic link to .local/bin
~/bin-go: symbolic link to .golang/bin
~/bin-js: symbolic link to .nvm/versions/node/v22.1.0/bin
优先系统二进制文件
为了确保系统的二进制文件优先于用户目录的文件,在我的 ~/.profile
中,我会确保 $PATH
的顺序正确:
# ...
# 隐藏默认 GOPATH
if [ -d "$HOME/.golang" ] ; then
GOPATH="$HOME/.golang"
fi
# 如果用户的本地 bin 目录存在
if [ -d "$HOME/bin" ] ; then
PATH="$PATH:$HOME/bin"
fi
# 如果 RUST 的本地 bin 目录存在
if [ -d "$HOME/bin-rust" ] ; then
PATH="$PATH:$HOME/bin-rust"
fi
# 如果 Python 的本地 bin 目录存在
if [ -d "$HOME/bin-py" ] ; then
PATH="$PATH:$HOME/bin-py"
fi
# 如果 Golang 的本地 bin 目录存在
if [ -d "$HOME/bin-go" ] ; then
PATH="$PATH:$HOME/bin-go"
fi
# 如果 Node.js 的本地 bin 目录存在
if [ -d "$HOME/bin-js" ] ; then
PATH="$PATH:$HOME/bin-js"
fi
export GOPATH
export PATH
通过这种设置,我可以更容易地验证是否调用了正确的二进制文件,并保持环境变量的整洁和可控性。
参考链接
- [Modern PATH environment variable](Modern PATH environment variable "Modern PATH environment variable")