| @技術/プログラミング

fish-shell に移行 してこれで .zshrc のお守り業から解放されたと思ってたが、最近異常にシェルの新規セッションの開始が遅くて死にそうになってた。特にやばいのが git mergetool したときで、これは内部的には沢山の fish のプロセスが起動して diff を調べて最終的に vimdiff で表示しているように見えた(僕は git config editor=vim です)。下手するとちょっとしたコンフリクトを修正するために vimdiff が起動するまで 15 分くらい待たないといけないことがあって、 20 年くらい前の Photoshop 作業の現場1みたいな感じになってた。これはかなりやばくて、生産性ががた落ちになる。 vimdiff が開くまでに待っている間に他のことやり始めて、気がつくと平気で夕方になってたりする。

fish-shell のバージョンを 2.7.0 に上げたことが原因かと思って、かつて快適に使えていた fish のバージョンに下げたりしてみたが解決しなかったが、以下の記事にたどり着いて $fish_user_paths への値の push をやめたところ解決した。

fish-shell での PATH の通し方として以下のようなのがよく出てくる。 Homebrew で keg only なやつを入れたときにも表示される。

set -U fish_user_paths $HOME/Library/Python/2.7/bin $fish_user_paths

しかしこれをやると $fish_user_paths にどんどんパスが積まれていってしまう。どうもこれが原因で遅くなるようだった。自分の環境でも echo $fish_user_paths してみたところかなり酷いことになっていた…。

↑の Qiita 記事では set -U fish_user_paths するときに第三引数を消せとあったが、それでは根本的な問題の解決にならない( Python やら Ruby やらいろんなものの実行ファイルを PATH に通したいはず)。自分は以下の方法で解決した。

set -x PATH /usr/local/bin $PATH

bash や zsh で export PATH=/usr/local/bin:$PATH とやるのと同じオーソドックスなやり方だと思う。

これだけではこれまでに散々肥えた $fish_user_paths は残ったままなので適当に set -U fish_user_paths '' とかやってあげると空になって起動が速くなる。

fish-shell の set -U はセッションをまたいでグローバルかつ永続的に設定される変数定義の方法っぽいので下手するとその環境で fish を使い始めてからずーっと残ってしまう可能性がある(端末を再起動したらリセットされるかも知れないけど)。

まとめ

  • set -U は基本的にしない
  • $fish_user_paths は設定ファイルの中では使わない
  • PATH を通したいときは set -x PATH を使う

追記 2020-05-23

set -x PATH /usr/local/bin $PATH がよいと書いていたが、 tmux を起動すると $PATH に重複してパスが登録されてしまう。ファイナルアンサーとしては以下。

$ set -g fish_user_paths /usr/local/bin $fish_user_paths
  • set -U は使わないではなく set -g する
  • $fish_user_paths は設定ファイルの中でも使ってオッケー
    • パスを通したいときは set -g fish_user_paths /usr/local/bin $fish_user_paths とやる
      set -x PATH /usr/loca/bin $PATH をやると tmux のセッションの中でパスがダブるため

  1. 何らかの処理を実行して処理が完了されるまでにめっちゃ時間がかかるのでその間にたばこを吸いに行くことが可能だったらしい