Edited at

fish shellが結構良かった話


Fishermanは名前を変更しFisherとなったため、それにともない内容を修正しました。

Yaourtはすでに開発が終了しているため、Yayを使うよう修正しました。


「fishいいよ」みたいな話は何度かちらっと聞いていたんですけど、ちょっと調べてみたところPOSIX非互換ということで、あまり興味を持てずにいました。

しかし最近Twitterで勧められて試しに使ってみたところ、すごく良かったので導入方法とかおすすめプラグインとか紹介してみたいと思います。

僕も入門したところなので、あんまり詳しくはないですけど。

似たような内容ですが、目的を絞った記事も書いたので興味があれば読んでみてください。

こっちの方がわかりやすいかもです。

ローカルリポジトリの管理方法


fishとは

Friendly interactive shellの略称だそうです。

ユーザーフレンドリさと対話的利用、わかりやすさを重要視しているようですね。

今までのシェルと同じように直感的に使えて、かつ古い悪習(caseの終了がesacとか)を捨て去っているという感じです。

なのでPOSIX非互換となっています。

POSIXというのは、シェルスクリプトの標準仕様のようなものです。

shPOSIX互換のシェルですね。

Bourne Shellを単にshと呼んだりするそうですが、UnixやLinuxにある/bin/shshそのものであったり、bash --posixへのリンクであったりするそうです。

bash --posixはBashの機能で、POSIX互換の機能のみ使用してスクリプトを動かすモードです。

自分の環境のshが本当にshなのか別のシェルなのか気になる方はls -l $(which sh)を実行すると見ることができるらしいです。

ls-lオプションはリンクが張られているかを表示するために付けてます。

閑話休題。

BashとかZshとかは、POSIX互換ではなくPOSIX準拠となっています。

というのも、POSIXの仕様で決められたものは全て動かせますけど、それ以外の拡張機能もあるのです。

互換ならどちらで書いてもどちらでも動きますけど、準拠は違います。

shで書いたものはBashで動きますけど、Bashで書いたものはshで動かないかもしれません。

Bashの拡張機能を使っているとshでは動きませんからね。

ちなみに非互換は完全に別物という意味です。

fishはこのPOSIX非互換が問題になるかもと思っていたんですけど、

コピペしてきたスクリプトとか動かすときだけshなりBashなり使えばいいですし、プラグイン紹介に書いてますけどBash互換のスクリプトを動かせるようなプラグインもあります。

そこまで困ることもないかもしれませんね。

以上、半分以上POSIXの話になっていた気もしますけど、fishについてでした。


fishのここが良かった



  • デフォルトで色々いい感じなので、ほぼ設定いらず


  • シンタックスハイライトの機能がすごい



    • 入力中のコマンドにもシンタックスハイライトが効く

    • コマンドやオプションが合っているかがひと目でわかる



  • コマンド履歴からの補完



    • コマンド入力中にインタラクティブに補完が見える



スクリーンショットはちょっと見た目をいじったあとのものです。

あと公式サイトにもアピールポイントが書いてありますね。


  • 履歴から自動で補完候補を表示

  • カラフルでわかりやすい


  • シンタックスがシンプルでわかりやすい

  • ブラウザでグラフィカルに設定をいじれる

  • わざわざ補完のためのコードを書かなくてもmanページから補完できる

  • 他のシェルでも使えるTabでの補完やシンタックスハイライトを強化しているだけなので、特別に新しいことを覚える必要がない

かなり雑な意訳ですがこんな感じでしょうか。


設定

基本的には~/.config/fish/config.fishに書いていきます。

でも設定ファイルを直接書くのって不安ですよね。

そこで、fishにはブラウザでグラフィカルに設定をいじる方法が用意されています。

fishでfish_configを実行してみてください。

上のスクリーンショットのようにURLが表示されているので、アクセスしてみましょう。

これなら簡単に設定をいじれそうですね。

あとブラウザで変更した設定は~/.config/fish/config.fishではなく~/.config/fish/fishd.<hostname>に保存されています。

<hostname>はLinuxに設定されたホストネームですね。

コンピュータの名前とも呼ばれます。

たぶんLinuxのインストールのときに、コンピュータの名前を設定してユーザを作ってユーザ名を設定して、みたいなことをしていますよね。きっと。

この~/.config/fish/fishd.<hostname>ですけど、自動生成されるものなので中身は書き換えないように注意してください。


Fisher

Fisherはfishのプラグインの管理ツールです。

似たようなツールとしてOh My Fishがありますけど、Fisherの方が後発なのと、FisherはOh My Fishのプラグインもインストールできるためこちらを使いたいと思います。


インストール

インストール方法はFisherのGithubのページにありますけど、ワンライナーです。

まず、それぞれのパッケージマネージャとかを使ってfishを入れてください。


ArchLinuxの例

yay -S fish


そしてfishを起動後、以下のインストール用のワンライナーを実行してください。

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


おまけ

Fisherはfishスクリプトで書かれています。

fishには関数(コマンド)が呼び出されたとき、その関数と同名のファイルを~/.config/fish/functions/以下から探し、その中の同名の関数を実行するという仕様があります。

fisherコマンドはこの仕様を利用して実装されているんですね。

つまり、上記のインストールスクリプトでは単にhttps://git.io/fisherというfishスクリプトを~/.config/fish/functions/fisher.fishに持ってきているだけです。

なのでブラウザでhttps://git.io/fisherにアクセスするとFisherのコードを見ることができますね。


fishをログインシェルにする

ログインシェル、またはデフォルトシェルとも呼ばれますね。

いきなりですけどArch Linuxではfishをデフォルトシェルにしないことが推奨されています。

詳しくはArchWikiのfish読んでください。

そんな事情もあり、他のLinuxディストリビューションでもfishをログインシェルにするかどうかは各自の判断に任せたいと思います。

ログインシェルにしたい人は以下のスクリプトを実行してください。


sh

chsh -s $(which fish)



fish

chsh -s (which fish)


ちなみにですけど、chshchange shell$()はコマンドの実行結果を取得するものです。

fishでは()ですね。


Fisherの使い方

fisher -h(fisher --help)でサブコマンドの一覧を見ることができます。

ちなみにですけど、fish起動してないとfisherコマンドは使えません

インストールおまけで書いた通りの理由ですね。

基本的にはfisher add user/fooでGitHubで公開されているプラグインをインストールすることができます。

削除するときはfisher rm fooです。

インストール済みのプラグインの一覧はfisher lsで見られます。

詳しいことはプラグイン紹介で書きますけど、僕が入れてるのはこんな感じですね。


プラグイン紹介

個人的なおすすめプラグインです。

まだfishを使い始めたところなので、それくらいの意識で読んでいただけるとちょうど良いかと思います。


oh-my-fish/theme-bobthefish

fisher add oh-my-fish/theme-bobthefish

VimにPowerlineというプラグインがあるんですけど、それのfish版です。

Gitのブランチとかステータスをわかりやすく表示してくれるツールですね。

Powerline Fontsを使っていますので、文字化けする人はインストールしてください。


ArchLinuxの例

yay -S powerline-fonts


また上記のリンクにもインストール方法が書かれています。

それでも文字化けするという人は、Cicaというフォントを入れてみて、それぞれのターミナルで設定してみてください。


ArchLinuxの例

yay -S ttf-cica


Cicaは様々なアイコンフォントがデフォルトで使えるプログラミング用フォントです。

もちろん日本語にも対応しています。

元はRictyというフォントで、そこにNerd FontsやNoto Emojiなどを合成したものになりますね。

Noto Emojiはそのまま絵文字、Nerd FontsはPowerlineを含む様々なアイコンフォントをまとめたフォントです。

ちなみにですけど、グリフ(文字)をまとめたものをフォントと呼んで、さらにフォント同士を合成することをパッチを当てる、と言ったりします。

RictyにNerd Fontsのパッチを当てる、みたいな感じです。

あとこれは蛇足なので聞き流してほしいんですけど、グリフってあんまり聞き慣れない言葉ですよね。

でもファンタジーが好きな人や中学生くらいで病にかかった人なら神聖文字(ヒエログリフ)とか聞いたことあるかもしれません。

閑話休題。

bobthefishの良さを知ってもらうため、少しデモを行いたいと思います。

まずGitのリポジトリのディレクトリに行きます。

カレントディレクトリの横に、gitでよく見かけるアイコンが見えますね。

ブランチのアイコンです。

次に、ファイルを変更してみます。

ここではREADME.mdを削除してみます。

表示が赤色に変わりましたね。

変更されたファイルがあるよ、という警告みたいです。

では、先ほどの変更をgit addステージングしてみます。

今度は黄色になりました。

コミットしていないステージングがあるよ、というのがひと目でわかりますね。

次はコミットを行ってみます。

コミットを行うと、緑色の表示に戻りましたけど、何やら+記号が付いていますね。

これはYour branch is ahead of 'origin/master' by 1 commit.をグラフィカルに示しているようです。

リモートブランチから進んだコミットがあるよ、という意味ですね。

面倒なのでpushはしませんけど、こんな感じです。

便利ですね。

あとこれは余談なんですけど、oh-my-fish/theme-bobthefishは実はOh My Fishのプラグインです。

名前を見て「あれ?」と思った方もいるかと思いますけど、https://github.com/oh-my-fishがOh My Fishのプラグイン用のGitHubアカウントになっているんですね。

Fisherのところでも書いたように、FisherではこれらOh My Fishのプラグインもインストールすることができます。

以上、bobthefishプラグインの説明のつもりだったんですけど、余談ばっかりだった気がしますね。

ところでbobthefishってなんて読むんでしょう。

Bob the fish?


jethrokuan/z

fisher add jethrokuan/z

移動系のプラグインです。

簡単に言うと、すべてのディレクトリへ直接移動できるプラグインですね。

以下はz fish~/.config/fishに移動する例です。

z fishではカレントディレクトリに関係のない相対パスを指定しているのに、ちゃんと~/config/fishに移動できていますね。

原理としては、コマンドの履歴のパスから指定された相対パスに部分一致するパスを検索しています。

なので行ったことあるディレクトリにしか行けないです。

もちろんTabでの補完もできます。

ちなみにですけど、部分一致なのでz foo/hoge/foo/barに移動したりもします。


FabioAntunes/fish-nvm

NVM使ってない人はいらないですね。

これは何のためにあるのかといいますと、NVMってBashに依存している部分があるんですよね。

なので、そのままではfishでは動きません。

それに対応するためのプラグインです。

ちなみに内部ではedc/bassという、Bash互換のスクリプトをfishで実行するためのプラグインを利用しています。


jethrokuan/fzf

fzfというコマンドのラッパーです。

fish用の便利なキーバイドを提供してくれます。

そもそもfzf自体を使ったことがないという人が多そうですけど、使いましょう。

とても便利です。

fzf自体は、入力された行データからインタラクティブに曖昧(fuzzy)検索を行ってくれるコマンド(fuzzy finder)です。

ちなみにGo言語製のツールです。

似たようなツールに同じくGo言語製のpecoがありますけど、こちらはfzfとは違い部分検索です。

最近はpecoでも曖昧検索ができるみたいです。

今回はfzfを使ってみたいと思います。

まずはfzfをそれぞれのパッケージマネージャなどで入れましょう。


ArchLinuxの例

yay -S fzf


次に、Fisherでfzfを入れます。

fisher add jethrokuan/fzf

そして、~/.config/fish/config.fish(fishの設定ファイル、設定を参照)がなければ作成し、以下の設定を書き込んでください。

set -U FZF_LEGACY_KEYBINDINGS 0

これはこのプラグインの古いキーバインドを使わないための設定です。

なぜキーバインドが新しくなったかというと、fish 2.4.0でキーバイドがコンフリクトしたからだそうです。

詳しい説明や使い方はjethrokuan/fzfのREADMEに書いてあります。

Ctrl+fファイルの曖昧検索ができます。

これは今回の記事で使うのに撮ったスクリーンショットですね。

Ctrl+rコマンド履歴の曖昧検索です。

ciと入力してるのにconfigとかひっかかってますね。

曖昧検索すごい。

最後に、Alt+oディレクトリを検索して移動ですね。

Alt+Shift+oで隠しファイルも検索できるようです。

あれ、これzの存在意義……?

fshなんていうタイポ検索でも安心ですね。

あとこれは余談なんですけど、fzffish関係ないところでも結構使いやすいです。

例えばホームディレクトリでls -aとかすると、ものすごい量の隠しファイルが表示されたりしますよね。

こういうとき、grepを使ってls -al | grep bashとする人が多いかもしれません。

そこでgrepの代わりにfzfを使うと……

インタラクティブな上にファジーに検索できますね。


decors/fish-ghq

ghqというコマンドのラッパーです。

補完とキーバインドを提供してくれます。

「あれ?fishはデフォルトでmanから補完できるんじゃなかったっけ?」と思った人がいるかもしれませんけど、いくつか追加で補完を入れてくれてるみたいです。

これもそもそもghqを使ったことがないという人が多いかもしれないですね。

でもとても便利なのでぜひ使いましょう。

そしてこれもまたGo言語製のツールです。

Go言語ってコマンドラインツール作るのにいい言語なんでしょうかね。

ghqはgit cloneを一箇所で管理してくれるツールです。

まずはお使いのパッケージマネージャでghqを入れましょう。

Go言語の環境がある人はgo getしてmakeでもいいですけど。


ArchLinuxの例

yay -S ghq


そしてFisherでfish-ghqを入れます。

fisher add decors/fish-ghq

使い方は簡単です。

まずghq get urlでリポジトリを持ってくることができます。

ここではhttps://github.com/utatatata/sushiをクローンしてみます。

git cloneそのまんまです。

~/.ghq/github.com/utatatata/sushiに入っていますね。

どうやら~/.ghq以下に<git host name>/<username>/<repository>という形でクローンされているみたいですね。

<git host name>github.comgitlab.combitbucket.orgなどです。

ちなみにですけどghq rootでクローンされるディレクトリを確認できます。

デフォルトでは~/.ghqですね。

これはghqの設定で変えることができます。

ghqの設定はGitの設定ファイルである~/.gitconfigに書き込むみたいですね。


.gitconfig

[ghq]

root = ~/Repositories
root = ~/.roswell/local-projects

ghq.rootは複数指定することができて、ghq getしたときリポジトリは一番上のパスの下にcloneされます。

そしてfishでghqを使う利点ですけど、とりあえずCtrl+gを押してみてください。

見たことある表示ですね。

これはfzfでghq getしてきたリポジトリを曖昧検索しています。

これはdecor/fish-ghqが、fzfやpecoが入っているとCtrl+gで検索を行ってくれるようになっているからですね。

とどのつまり、これを使えばCtrl+gで目的のリポジトリに素早く移動できるわけですね。


まとめ

fish、どうでしたでしょうか。

ほとんどのプラグインで設定ファイルを書いていませんでしたよね。

そして設定も簡単にいじれます

またこの記事を読みながら手を動かしてくださっていた人ならもうわかっていただけたと思いますけど、補完とサジェストとシンタックスハイライト、とても強力ですよね。

とにかく楽だ……

しばらくはfishを使っていきたいと思います。


参考文献

Public Domain Lisp Logo Set

POSIX - Wikipedia

Unixシェル - Wikipedia

Friendly interactive shell - Wikipedia

h・bash・zsh等, shellの違いでハマりやすい部分とか - 水底