Photoruction工事中!

Photoructionの開発ブログです!

Fishシェルを使いましょう

Fish(フィッシュ・シェル)はFriendly Interactive SHellの略で、UNIX系システムのシェルであり、UX(ユーザーエクスペリエンス)に長けたシェルです。そのため他のシェルに比べて仕事が効率的に出来ることが多いです。

FishのASCIIロゴ
FishのASCIIロゴ

Linuxディストリビューションの兼ね合いでBashシェルを使用する方は多いかもしれません。そこからもっと使い勝手のいいZshに移った方や、macOSのアップグレードでデフォルトシェルがZshを使用されている方はいらっしゃると思いますが、それもオワコンと断言できます!

Fishはホームページには90年代のためのシェルと書いてありますが、私は21世紀のシェルであると盲信しています。他のシェルを使用する中でFishを使い始めたらもう手放せません。

BashZshの時にコマンドを打つたびにmanページ(ターミナルからアクセスできるUNIX系マニュアルコマンド)を読んだり、ググったりしていましたし、なんとかcompletionのパッケージをインストールしたりしていましたが、Fishではそれをきにすることなく、manページから自動的に解析し、コマンドの先頭文字を書きながらTabキーを押すことでコマンドの説明やオプションやサブコマンドをわかりやすい色使いで、表示してくれます。過去に入力したコマンドを薄いグレー色で表示し、キーを押すと保管してくれます。シンタックスハイライトも美しいですし、右側のプロンプトの設定などもできます。

Fishでのlsで始まるコマンド補完挙動
Fishでのlsで始まるコマンド補完挙動

Fishでのlsコマンドのオプション補完挙動
Fishでのlsコマンドのオプション補完挙動

Zshでもそんなことができるぞ」とおっしゃる方はいらっしゃるかもしれませんが、これはいわゆる「Out of the Box」(何のカスタマイズもない)Fishの振る舞いです。

では導入方法を見ていきましょう:

Fishを導入

インストール

各プラットフォームのインストール方法は公式ホームページから確認できます。

fish shell

macOS

Homebrew:

brew install fish

権限がない、もしくはシステムに痕跡を残したくない方は単独のアプリ(Automatorを使用しラッパー(Wrapper))をダウンロードし起動することができます。

Linux

Homebrewを導入していれば上記macOSのコマンドでも導入できます。

ディストリビューションが多くて、代表的なものですと:

sudo apt-add-repository ppa:fish-shell/release-3
sudo apt update
sudo apt install fish
dnf install fish

Unix

pkg install fish
pkg_add fish

Windows

MSYS2を導入している方は:

pacman -S fish

Fishをデフォルトシェルとして設定

インストールが成功したら、Fishをデフォルトシェルに設定することがおすすめです。多くのシステムではFishは同梱されていないことが多いので、システムにFishコマンドの場所を教えてあげる必要があります。

システムレベルで現在のログインしているユーザーのシェルをFishにするのにやることは二つ。

  1. /etc/shellsというデフォルトシェル一覧ファイルにFishコマンドの場所を追加
sudo sh -c 'echo $(which fish) >> /etc/shells'
  1. 現ユーザーのデフォルトシェルを設定
chsh -s "$(which fish)"

上記はUNIX系の環境であれば動くはずですが、つまづいたらググるもしくはチャチャる(ChatGPT)で調べてみてください。

Fishで出来ること

基本的に他のシェルで出来ることはFishで、もっと優雅にできます。

シェルスクリプトをプログラミングすることもできますし、シェルのプロンプトをカスタマイズすることができます。

Fish言語

シェルスクリプトのようにFishでプログラミングするためのFish言語が存在します。

細かくみたい方はこちらをご参考ください。

The fish language — fish-shell 3.6.1 documentation

この記事では代表的なところをご紹介します。

変数

全ての変数は配列です。Fishではリストとも呼びます。Bashと同じく配列メンバーをスペースで分けますが、ダブルコーテーションもしくはバックスラッシュでスペースをエスケープすることができます。

set var "foo bar" banana
set var foo\ bar banana # バックスラッシュでも同じ結果
printf %s\n $var

結果:

foo bar
banana

変数の代入時にコマンド結果を使用してもいいし、実値とコマンドを混ぜることができます。

set numbers 1 2 3 (seq 5 8) 9
printf '%s\n' $numbers

結果:

1
2
3
5
6
7
8
9

配列の一部を表示:

echo $numbers[5..7]

結果

6 7 8

関数

Fishの関数はコマンドのように使用ができ、補完するときの説明も追加することができます。

function hoge --description "関数の説明はこちら"
    echo $argv
end

Fishでの関数補完時に説明も表示されます
Fishでの関数補完時に説明も表示されます

Fishでの関数補完時に説明も表示されます

$argvは他のPOSIXシェルで使われる位置パラメータ($1,$2, …)の代わりであり、上記のように配列になっています。

ユニバーサル変数

これは他のシェルに見当たらないすごい機能であり、ユーザが起動中の全てのFishシェルに対して横断的且つ永久に変数値を設定することができるすごい機能です。つまりシェルの設定ファイルなどを手動で編集することなく、マシンを再起動しても残る変数です。

# このコマンドは、全てのfishシェルに対してプロンプトを青色に設定するものです。
set -U fish_color_cwd blue

上記のコマンドで設定された変数は~/.config/fish/fish_variablesに書き出されることがこの挙動の秘密のようです。

FishではPATH変数がユニバーサル変数として定義されています。

注意事項

Fishはユーザー体験や使いやすさに力を入れたシェル環境です。そのため、ZshみたいにBashPOSIXの互換性を維持するというミッションはないので、基本的に多くのBashの書き方は使用できません。バックティック```でコマンド実行することや、シェルの展開・置換(Bash expansion)は使えません。その理由はこういったシェル実装にバグやクセが多いからだそうです。その代変えとなるものはドキュメンテーションに書いてあります。

Bashシンタックスに慣れた方はドキュメンテーションの「BashユーザーのためのFish」(英語)をご参考願います。

Fish for bash users — fish-shell 3.6.1 documentation

Bashの書き方として使えて、Fishで使えない書き方の例(Wikipedia#Bash/fish_translation_table)より)

機能名 Bash Fish 備考
Fishでは中括弧は使えません ${var} $var Fishでは中括弧は使えません
配列の拡張 "${var[@]}" $var Fishの変数は配列なので、そのまま拡張されます。中括弧は使えません。
明示的なサブシェル (expression) fish -c expression サブシェルの呼び出し
プロセス置換 <(expression) (expression | psub) プロセス置換
変数代入 var=value set var value 単純にイコールサインの代入はできません。全てをsetコマンドで通す必要があります。
文字列処理(プレフィックスサフィックス、貪欲パターン、貪欲でないパターン) var=a.b.c
"${var#*.}" #b.c
"${var##*.}" #c
"${var%.*}" #a.b
"${var%%.*}" #a
string replace --regex '.*?\.(.*)' '$1' a.b.c #b.c
string replace --regex '.*\.(.*)' '$1' a.b.c #c
string replace --regex '(.*)\..*' '$1' a.b.c #a.b
string replace --regex '(.*?)\..*' '$1' a.b.c #a
stringコマンドを使用する必要があります。
文字列置換 "${HOME/alice/bob}" string replace alice bob $HOME stringコマンドを使用する必要があります。
変数のエクスポート export var set --export var setコマンドで通す必要があります。
関数のローカル変数 local var デフォルト仕様 関数の変数はデフォルトでローカルです
引数ベクター操作:シフト shift set --erase argv[1]
計算 $((10/3)) math '10/3' expr 10/3は外部コマンドなので、両方のシェルに使用できます
エスケープシーケンス $'\e' \e
環境変数を設定しながら実行 LANG=C.UTF-8 python3 env LANG=C.UTF-8 python3 env LANG=C.UTF-8 python3は外部コマンドなので、両方のシェルに使用できます

まとめ

Fishは大変使いやすいシェルでおすすめです。使いやすいし、Tabキー補完や履歴呼び戻しが直感的です。ぜひ使ってみてください。

株式会社フォトラクションでは一緒に働く仲間を募集しています