世界を動かす技術を、日本語で。

Zoxide: より良いCDコマンド

概要

zoxide は、よく使うディレクトリへの高速移動を実現する スマートcdコマンドLinux, macOS, Windows など、主要なシェルに対応。 fzf との連携やデータインポートなど 柔軟な拡張性 を提供。 簡単なインストール方法 と幅広い サードパーティ統合設定やカスタマイズ も豊富で、様々なワークフローに対応。

zoxide概要

  • zoxide は、 zautojump に触発された次世代cdコマンド
  • 使用頻度の高いディレクトリを記憶し、 数キーでジャンプ 可能
  • すべての主要シェル( bash, zsh, fish, PowerShell など)に対応
  • fzf によるインタラクティブ選択や補完機能もサポート
  • シンプルなコマンド構文で、従来のcdコマンドと互換性

基本的な使い方

  • z foofoo を含む最も使用頻度の高いディレクトリに移動
  • z foo barfoobar を含むディレクトリにジャンプ
  • z foo /foo で始まるサブディレクトリに移動
  • z ~/foo:通常のcdコマンドのようにも利用可能
  • z foo/:相対パス移動対応
  • z ..:1階層上のディレクトリへ
  • z -:直前のディレクトリに戻る
  • zi foofzf を使ったインタラクティブ選択
  • z foo<SPACE><TAB>:補完候補の表示(bash 4.4+/fish/zsh, zoxide v0.8.0+)

インストール方法

  • Linux / WSL
    • 推奨:インストールスクリプト curl -sSfL https://raw.githubusercontent.com/ajeetdsouza/zoxide/main/install.sh | sh
    • 主要ディストリビューションでのパッケージマネージャ対応
      • 例:apt install zoxide, dnf install zoxide, pacman -S zoxideなど
  • macOS
    • Homebrew: brew install zoxide
    • cargo: cargo install zoxide --locked
    • その他(asdf, conda, MacPorts, nixpkgs等)にも対応
  • Windows
    • 推奨:winget install ajeetdsouza.zoxide
    • 他:Chocolatey, Scoop, conda-forge, cargo等
  • BSD / Android
    • 各種パッケージマネージャ、またはインストールスクリプトで対応

シェルごとのセットアップ

  • Bash eval "$(zoxide init bash)"~/.bashrc の末尾に追加
  • Zsh eval "$(zoxide init zsh)"~/.zshrc の末尾に追加 ※補完機能はcompinit後に記述
  • Fish zoxide init fish | source~/.config/fish/config.fish に追加
  • PowerShell Invoke-Expression (& { (zoxide init powershell | Out-String) })$profile の末尾に追加
  • その他 Elvish, Nushell, Tcsh, Xonsh, POSIX Shellにも対応

fzfとの連携(オプション)

  • fzf はzoxideのインタラクティブ選択や補完に利用
  • fzfのインストール推奨(最低バージョンv0.51.0)

既存データのインポート(オプション)

  • autojump, fasd, z, z.lua, zsh-z, ZLocation 等からデータ移行可能
  • zoxide import --from=autojump "/path/to/autojump/db"等のコマンドで実行
  • 各OSやプラグインによるパス指定要確認

設定・カスタマイズ

  • zoxide init 時のフラグ
    • --cmd:コマンド名の変更(例:--cmd jjコマンドに)
    • --hook:ディレクトリスコア更新タイミング(none, prompt, pwd)
    • --no-cmd:z/ziコマンド定義を抑止
  • 環境変数
    • _ZO_DATA_DIR:データベース保存ディレクトリ
    • _ZO_ECHO:ジャンプ前にディレクトリ表示(1で有効)
    • _ZO_EXCLUDE_DIRS:除外ディレクトリ指定(:や;で区切る)
    • _ZO_FZF_OPTS:fzfのカスタムオプション
    • _ZO_MAXAGE:データベースのエントリ最大数(デフォルト10000)
    • _ZO_RESOLVE_SYMLINKS:シンボリックリンク解決(1で有効)

サードパーティ統合

  • メールクライアント :aerc
  • macOSランチャー :alfred-zoxide, raycast-zoxide
  • Windowsコマンド強化 :clink-zoxide
  • テキストエディタ :emacs(zoxide.el), vim/neovim(zoxide.vim, telescope-zoxide)
  • ファイラ :lf, nnn, ranger, joshuto, felix, yazi, xplr, rfm等
  • tmuxセッション管理 :sesh, tmux-session-wizard, tmux-sessionx
  • その他 :zsh-autocomplete, xxh, zabb, zesh, zellij等

注意事項・補足

  • Debian系ディストリ はパッケージ更新が遅い場合があるため、スクリプトインストール推奨
  • 環境変数の設定方法 はシェルごとに異なるため、公式Wikiを参照
  • 詳細なマッチングアルゴリズム や使い方は公式ドキュメント参照

zoxide の導入により、日々のディレクトリ移動が圧倒的に効率化 多彩なシェル・ツール連携 で、あらゆるワークフローにフィット シンプルな設定と強力なカスタマイズ性 で、初心者から上級者までおすすめ

Hackerたちの意見

ほんとにいいよね。fzfとzoxideは、僕の中で一番変革をもたらしたCLIツールだよ。ターミナルがすごく快適に感じる。

実は、zoxideをラップするgit worktree対応の関数「w」を作ったんだ。これを使うと、メインのworktreeに切り替えてzを実行して、元のworktreeに戻れるんだ。これで、zoxideが別のworktreeに切り替わるのがイライラしなくなるし、新しいworktreeはすぐにzoxideのスコアを引き継ぐよ。他のworktreeはzoxideのデータベースから消去して、gitリポジトリ内ではzの代わりにwを使う感じ。最近はgitからjjに切り替えたから、しばらく使ってないけどね。

zoxideをしばらく試してみたけど、なんかふわふわした感じが嫌で、使い道のほとんどはZSHの履歴検索で90%解決できることに気づいたんだ。要するに、常に変動するショートカットのセットを持つことになるから、結果がちゃんと得られたか確認しないといけなくて、間違って別の場所に行ってしまうこともある。タブ補完や履歴の方がずっと予測可能だから、そっちの方が楽だな。違うワークフローや環境の人には良いかもしれないけどね。

うん、最近試してるけど、使い続けたいかはまだ決めかねてる。今一番イライラしてるのは、2つのディレクトリ「thing」と「thing-api」があって、「thing」で作業することが多いんだけど、「z thing」を実行すると最初に「thing-api」に行っちゃうんだ。それで、もう一度「z thing」を実行しないといけなくて、普通のcdコマンドでタブ補完や履歴検索した方が楽だなって思う。

俺は普段、プロジェクトA、プロジェクトB、プロジェクトCみたいな数個のフォルダでしか作業しないから、そこの優先度を教えたら、名前の一部を打つだけでちゃんと動いてくれるんだよね。

fzfの補完を使って、source /dev/nullと ショートカットを使ってるよ。例えば、cd ~/ とか、cd -で前のディレクトリに戻る時に使ってる。

そうだね、「z d」でダウンロードフォルダにいつでも行けるのは、ふわっとしたマッチよりもずっと強力だし、残念ながらプロジェクトは予測可能な入力メカニズムを追加したくなかったみたいだけど、将来的には変わるかもね…。

Zshの履歴を使って特定のフォルダに移動するのってどうやってるの?例えば、いつもホームディレクトリ(~)からcdを始めるってこと?相対ディレクトリにcdする方が通常はキー入力が少ないから聞いてるんだけど(関連するディレクトリで作業してる前提ね)。でもそうすると、履歴のcdエントリーは特定の開始パスを想定しちゃうから、履歴から呼び出すのが普遍的に役立たないってことになるよね?それと、>「問題は、結果がちゃんと得られたかを常に確認しなきゃいけないし、間違った場所に行ってないかも気にしなきゃいけないこと。」って言ってたけど、なんで現在のパスをプロンプトに追加しないの?それがないと、どのディレクトリにいるのか全然分からなくて、どうやって作業するのか想像もつかないよ。

最近zoxideについて発見した便利なことは、basedirフラグがあることだね。理論的には、今いるディレクトリやgitのルートに基づいてクエリをスキャンできるんだ。例えば、alias zg=‘zoxide —basedir $(git rev-parse --show-toplevel)’みたいな感じ。https://github.com/ajeetdsouza/zoxide/pull/1027

わあ!それは本当に便利だね!

僕にとって、このシンプルなツールは最高のコマンドラインチェンジャーだよ!フォルダーツリーを移動するためにたくさんのコマンドを使う代わりに、行きたいところにジャンプできる。あと、使ってるいいツールは、シェル用のFish(https://fishshell.com/)、プロンプト用のStarship(https://starship.rs/)、ファイルプレビュー用のbat「翼のある猫」(https://github.com/sharkdp/bat)だね。

eza(https://github.com/eza-community/eza)も好きで、これは現代的なlsだよ。でも、Fishが一番のゲームチェンジャーかな。

rgとfdが一番使ってるかな。grepやfindに比べて、ユーザー体験がかなり向上してる。

あと、Atuin(https://atuin.sh/)を使って、シェルの履歴を(オプションで共有)してるよ。

「j」ってコマンドでautojump使ってるんだけど、zoxideの方がいいところってあるの?

autojumpは使ってないけど、READMEをざっと見た感じ、zoxideが提供しているnushellとの統合がないみたい。Pythonベースじゃなくてネイティブバイナリだから、実行も速いかもしれないね。試したPythonベースのCLIヘルパーは、シンプルなコマンドでもちょっとした遅延があったけど、zoxideはすごく速くて、ヘルパーを呼び出したことすら忘れちゃうくらい。

自動ジャンプを何年も使ってたんだけど(Debianで)、ここ数ヶ月でジャンプ履歴を何度も失ったんだ。どうやら新しいバージョンで修正された既知のレースコンディションバグがあったみたい。だから、zoxideに移行したら、問題なく動いてるよ!ただ、jの代わりにzを使うのに慣れるのが大変で、筋肉記憶を調整するのが難しいから、エイリアスを設定しようかな。

自動ジャンプの初期開発者だよ:zoxideを使って。数年前に自動ジャンプのメンテナンスを誰かに引き継いだけど、今は放置されてる。RustはこのアプリケーションにはPythonより優れてるしね。

スタンドアロンの「cd」を実装するのがどれだけ面倒か、改めて思い知らされるね。セキュリティ上の理由がたくさんあるのはわかるけど、親プロセスが子プロセスの環境変数の最終状態を簡単に読み取って、統合できたら便利だと思う。シェルにはサブプロセスの環境変数を受け入れるための構文があってもいいよね。例えば、行の最初を「=」で始めて、設定された環境変数を全部吸収するみたいな。カスタムのcdツール、「custom-cd-bin」みたいなのを作って、ただPWD変数を変更するだけでいいんだ。$ =custom-cd-bin ./foo これ、実際に作ることはないだろうけど、夢のシェルのために考えてみるよ。setenvをラップするような面倒なことが必要になるだろうけど。

うーん、それってまさに「source」のことだね。dotfiles以外ではあまり使われないけど…まあ、全ての変数とかを引き継ぐからね。もしスクリプトの最後で明示的に遷移させたいなら、姉妹コメントがやったように「source <(bash the-script|grep -Pom "xx inherited variables\n(.*?)\n yy inherited variables")」ってやればいいよ。

それって、wait(2)の前に/proc/$PID/environを読む感じ?

cdの代替手段は、13歳の頃のコンピュータの思い出からPTSDを引き起こすんだ。親の286でDOS 3.3を使ってた時、最近ノートンのユーティリティをいくつかインストールしたんだけど、その中にncd(Norton Change Directory)があって、ディレクトリのデータベースを持ってて、正規表現でファジーcdができたんだ。そんなツールの力を見てすごく感動してたんだけど、ある日、コードの実験をしてたディレクトリにncdしようとして、全部削除しちゃったんだ。残念ながら、補完が別のディレクトリに送っちゃって、親の税務書類を全部削除した後に気づいたんだ。DOS 3.3には後のDOSのバージョンみたいにundeleteコマンドがなかったから、父の同僚が外部ツールを使ってデータを復元しようと一晩中頑張ってくれたよ。良いこととしては、彼がDOS 6.22をインストールしてくれたこと(本当に遅れてたけど)。

その晩にFATが何かを学んだんだね。

nushellは、こんな感じで任意のレベルまで上がれるよ:cd ..../foo。これがcdで唯一恋しかった機能だから、もう大丈夫。

しばらくzoxideを使ってたけど、ziコマンドで目的のディレクトリを探せることに気づいてからは、ほとんどの場合デフォルトのzコマンドの代わりに使ってるよ。

HNでの大きな話題になってから、.bashrcファイルをシンプルにするためにこれを日常的に使ってテストしてる。eval "$(zoxide init bash --cmd cd)"で使ってるから、筋肉の記憶でCDも続けられるんだ。

  • Zoxideが知ってる複数の/fooディレクトリ、例えば/foo/と/abc/foo/があるときに、cd abc fooで両方のパスに行けるのがいいね。
  • でも、CWDの外のフォルダに対してタブ補完するためにcd foo**をしなきゃいけないのはあんまり好きじゃない。タブ補完中毒の俺には遅く感じるんだよね。
  • それに、もし直接cd foo/bar/batzに行った後にcd barを試すと、Zoxideは参照がないんだ。データベースを構築するためには、各ディレクトリに個別にCDしなきゃいけない。ネットで見かけたスクリプトがあって、各サブディレクトリにCDして完全なディレクトリ構造をZoxideのデータベースに入れてくれるみたい。公式に気に入ったかどうかはまだわからないけど、エイリアスやシンプルなタブ補完に戻るかもしれないな。タブ補完をCWDから逆に正確なディレクトリ名にするためのロジックを使ってるんだ。cd ../../../etcの代わりにね。 https://gist.github.com/GNOMES/6bf65926648e260d8023aebb9ede9...