Mac
fish
memo
shell
備忘録

Macでfishを使って良い感じなシェル環境をお手軽に作る


はじめに

この間カンファレンスに行った時に発表者が使ってたシェルがカッコ良かったのでfishに変えてみ他のでその備忘録。

元々、zshを使ってたけどそこまでカスタマイズしてたわけではないので移行はすんなりでした。

fishに関して詳しくはこちらに詳しく載ってるので割愛。

簡単に書くとカスタマイズしなくてもデフォルトで結構行けてるzshみたいなものです。


本体の導入

まずは本体の導入。と言ってもbrewするだけです。

$ brew update && brew install fish

続いてデフォルトシェルを変更

$ echo /usr/local/bin/fish | sudo tee -a /etc/shells

$ chsh -s /usr/local/bin/fish

これでTerminalを再起動するればシェルがfishに変わります。

続いてパッケージマネージャをインストールします。なお、ここからはfish上での作業なのでbashやzshでは動かないので先に上記の作業で本体を入れてシェルを切り替えてください。

$ curl https://git.io/fisher --create-dirs -sLo ~/.config/fish/functions/fisher.fish

これで最低限必要なもの導入は完了です。


プロンプトを変更する

続いてプロプントを変更します。デフォルトでも良い感じの見た目のものはあったのですが、gitのstatusとかに対応したものがなかったのでfisherで新しいテーマを入れます。

$ fisher add oh-my-fish/theme-bobthefish

ただ、これ単体だと文字化けするのでPowerline系のフォントを追加してTearminalのフォントを変えます。

$ git clone https://github.com/powerline/fonts.git                                                

$ cd fonts/
$ ./install.sh

これでPowerline系のフォントがインストールされました。私はRobot Monoにしています。


履歴検索を追加

fishは履歴からのコマンドが補完でき非常に重宝しますが一方でbashやzshで良く使う履歴検索自体はデフォルトで無いようです。

なので、pecoを入れてそちらでコマンド検索できるようにします。

$ brew install peco                                                                               

$ fisher add oh-my-fish/plugin-peco
$ vim ~/.config/fish/config.fish

中身はこちら。


~/.config/fish/config.fish

function fish_user_key_bindings

bind \cr 'peco_select_history (commandline -b)'
end

これでシェルを再起動すればC-rで履歴が検索できます。


ディレクトリの履歴移動

zshだとcdにpushがデフォルトで付くのでpopdを使ってディレクトリを移動してたかと思います。

fishにその補完は無いのですがより便利な拡張が入っています。popdに相当する機能はprevdとnextdです。

$ mkdir -p dir1/dir2 

$ cd dir1
$ cd dir2
$ pwd
/tmp/dir1/dir2
$ prevd # 戻る
$ pwd
/tmp/dir1/
$ prevd # 戻る
/tmp/
$ nextd # 進む
/tmp/dir1

popdと同じことができますね。dirhで一気に移動するとこともできます。

$ dirh

3) /tmp
2) /tmp/dir1
1) /tmp/dir1/dir2
/tmp/dir1/dir2/dir3
$ prevd 3
$ pwd
/tmp


Bashとの互換


非互換一覧

fishはBashやzshのようにPOSIX互換ではありません。なので色々仕様が違うようなのですが例えば以下のような差分があるようです。


  • 標準エラー出力のリダイレクトは^を使う

  • 変数はNAME=hogeではなくset NAME hogeを使う

  • 終了ステータスは$?ではなく$statusを使う

  • コマンド置換はcommand$(command)ではなく(command)を使う


Bashラッパー

自分で書くときは覚えようの世界かもですが、チュートリアルとかで他人の手順を参考にする時に不便です。

なので、bassというプラグインを入れます。

$ fisher add edc/bass

これでbashでの操作ができるようになります。

$ echo $(date)

fish: $(...) is not supported. In fish, please use '(date)'.
echo $(date)
^
$ bass 'echo $(date)'
Sat Apr 13 22:45:05 PDT 2019


まとめ

とりあえずzshに疲れたら非互換がちょっと面倒ですがfishでやるのも良いかと思います。あまりカスタマイズせずにカッコいいのは良いこと。

それではHappy Hacking!


参考