zoxide
> zoxide — 一个更智能的 cd 命令,让你告别频繁的目录切换痛苦
如果你跟我一样,每天要在终端里开几十个窗口,切几十次目录,那你大概率对 `cd` 这个命令又爱又恨。爱的是它简单,恨的是它太傻——明明我上个小时刚进过那个深藏在 `/var/www/project/src/components` 的目录,现在又得敲一遍完整路径,或者用 `cd ..` 一层层往回退,再重新 `cd` 进去。手指头都快磨出茧子了。
这就是 zoxide 要解决的核心问题:**用模糊匹配 + 频率学习,让你用最短的输入跳到最想去的目录**。
### 它是怎么做到的?
zoxide 本质上是一个增强版的 `cd`,但它背后有一套轻量级的排名算法。它会记录你每次进入过的目录,根据访问频率、最近访问时间、目录深度等维度给每个目录打分。下次你输入 `z foo`,它不会像 `cd` 那样严格匹配 `foo` 这个名字,而是会从你的历史记录里找出所有跟 `foo` 相关的目录,然后挑出得分最高的那个跳过去。
举个例子:你经常去 `/home/me/work/project-foo`,偶尔去 `/tmp/foo-test`。当你输入 `z foo` 时,它会直接跳到第一个目录,因为你去得最多。如果你想去第二个,输入 `z foo test` 或者 `z foo tmp` 就能精准匹配。这比 `cd` 的 Tab 补全快了不止一个量级。
更贴心的是,它完全兼容原有的 `cd` 命令,不会破坏你现有的肌肉记忆。你可以继续用 `cd`,也可以用 `z` 来加速,两者互不干扰。
### 下载和安装
zoxide 的官方网站在这里:[https://github.com/ajeetdsouza/zoxide](https://github.com/ajeetdsouza/zoxide)(GitHub 仓库,文档和源码都在)。如果你是 macOS 用户,可以直接用 Homebrew 装,一条命令搞定:
```bash
brew install zoxide
```
Linux 用户用包管理器也很方便:
```bash
# Ubuntu/Debian
sudo apt install zoxide
# Arch Linux
sudo pacman -S zoxide
# Fedora
sudo dnf install zoxide
```
Windows 用户别慌,它支持 scoop 和 winget:
```bash
scoop install zoxide
# 或者
winget install zoxide
```
如果这些都不行,你还可以去 GitHub Releases 页面下载编译好的二进制文件,扔到 PATH 里就能用。体积极小,不到 1MB,属于那种“装了就忘不掉”的工具。
### 安装后的配置
装完只是第一步,还得让 shell 认识它。根据你用的 shell 不同,要在对应的配置文件里加一行。zoxide 支持 bash、zsh、fish、powershell 等主流 shell。
**如果你用 bash**,在 `~/.bashrc` 末尾加上:
```bash
eval "$(zoxide init bash)"
```
**如果你用 zsh**,在 `~/.zshrc` 末尾加上:
```bash
eval "$(zoxide init zsh)"
```
**如果你用 fish**,在 `~/.config/fish/config.fish` 末尾加上:
```bash
zoxide init fish | source
```
**如果你用 PowerShell**,在 `$PROFILE` 里加上:
```powershell
Invoke-Expression (& { (zoxide init powershell) })
```
加完之后重新加载配置文件(比如 `source ~/.zshrc`),或者新开一个终端窗口,zoxide 就开始工作了。
### 基础使用教程
安装配置好之后,你不需要任何学习成本,直接把它当成 `cd` 的超级版本来用就行。最常用的命令就这几个:
**1. `z <关键词>` —— 跳到最匹配的目录**
```bash
# 假设你去过 /home/me/projects/python/awesome-app
z awesome-app # 直接跳过去
z py awe # 模糊匹配也能行
z app # 如果这个目录访问频率最高,也会跳到它
```
**2. `zi <关键词>` —— 交互式选择(模糊搜索)**
有时候关键词太宽泛,匹配到多个目录,你不确定哪个是想要的。这时候用 `zi` 会弹出一个交互式列表,你可以用方向键选择,或者继续打字筛选:
```bash
zi proj
# 显示:
# 1. /home/me/projects/python
# 2. /home/me/work/projects
# 3. /tmp/old-projects
# 输入编号或继续打字
```
**3. `zq <关键词>` —— 只输出路径,不跳转**
这个适合在脚本里用,比如你想把路径存到变量里,或者传给其他命令:
```bash
echo $(zq awesome-app)
# 输出:/home/me/projects/python/awesome-app
```
**4. `zoxide add <路径>` —— 手动添加目录到数据库**
zoxide 默认会自动记录你 `cd` 过的目录,但如果你用其他方式进入目录(比如通过文件管理器、tmux 会话),可以手动添加:
```bash
zoxide add /some/deep/path
```
**5. `zoxide remove <路径>` —— 删除记录**
如果你去过一个临时目录,后来不想让它出现在搜索结果里:
```bash
zoxide remove /tmp/temp-build
```
### 进阶技巧
用熟了之后,你会发现 zoxide 还有很多隐藏玩法,能进一步解放双手。
**技巧一:用别名替代 cd**
如果你像我一样,已经习惯了 `cd` 这个动作,可以给 `z` 起个别名,这样每次敲 `cd` 时实际上是在用 zoxide:
```bash
# 在 shell 配置文件里加上
alias cd='z'
```
但注意,这样会完全覆盖原生的 `cd`,如果你偶尔需要严格按路径跳转,可以用 `\cd` 来调用原生命令(反斜杠会跳过别名)。
**技巧二:配合 fzf 实现终极模糊搜索**
`zi` 虽然好用,但 fzf 的交互式体验更丝滑。你可以把 zoxide 和 fzf 结合起来,实现类似“输入关键词 → 实时模糊搜索 → 回车跳转”的效果:
```bash
# 定义一个函数,集成 zoxide + fzf
j() {
local dir
dir=$(zoxide query --list | fzf --height 40% --reverse)
if [ -n "$dir" ]; then
cd "$dir"
fi
}
```
把这个函数加到 shell 配置里,以后输入 `j` 就会弹出 fzf 的搜索窗口,你可以打字、用方向键、甚至用 Ctrl+R 翻历史,选中后直接跳转。
**技巧三:用环境变量控制行为**
zoxide 有几个环境变量可以调节它的行为:
- `$_ZO_DATA_DIR`:指定数据库文件存放位置,默认在 `~/.local/share/zoxide`。
- `$_ZO_MAXAGE`:数据库记录的最大存活天数,默认是 365 天,超过的记录会被清理。
- `$_ZO_RESOLVE_SYMLINKS`:是否解析符号链接,默认不解析。
比如你想让数据库不占用太多空间,可以设置:
```bash
export $_ZO_MAXAGE=90 # 只保留 90 天内的记录
```
**技巧四:在 tmux 里共享数据库**
如果你经常开多个 tmux 窗口,每个窗口的 shell 进程是独立的,默认情况下 zoxide 的数据库是共享的(因为它用的是同一个文件)。但如果你发现不同窗口的记录没有同步,检查一下是不是每个 shell 都正确初始化了 zoxide。最稳妥的做法是在 tmux 的配置里统一设置环境变量,或者把 `eval "$(zoxide init zsh)"` 写到全局的 shell 配置里(而不是 `~/.zshrc` 这种每个会话独立的文件)。
**技巧五:用 `zoxide query --list` 导出所有记录**
如果你想备份或分析自己的目录访问习惯:
```bash
zoxide query --list > ~/zoxide_backup.txt
```
这个命令会输出所有记录的完整路径,每行一个。你可以用 `sort | uniq -c` 来统计每个目录的访问频率,看看自己平时都在哪个项目里摸鱼。
### 一点小提醒
zoxide 虽好,但有个小坑:如果你经常用 `cd` 进入临时目录(比如 `/tmp/build-xxx`),这些目录也会被记录到数据库里,导致搜索结果变脏。我的习惯是定期用 `zoxide remove` 清理,或者在进入临时目录后主动删除记录。另外,如果你用的是 WSL,zoxide 在 Windows 和 Linux 文件系统之间跳转可能会有点慢,因为跨文件系统的路径解析需要时间,但日常使用完全没问题。
总的来说,zoxide 是我装机必备的工具之一,没有它我可能每天得多敲几百次 Tab 键。如果你还在忍受 `cd` 的笨拙,花 5 分钟装一个 zoxide,你会回来感谢我的。