なんとなく新しいshellに手を出してみたくなった。fishを触ってみたところ良さそうだったので移住のためのメモを作成。
fishの特徴
fish (Friendly Interactive SHell)は分かり易さ・ユーザフレンドリーに重きを置いた敷居の低さと実用性の両方を兼ね備えたシェル。 以下のような特徴がある。
- オートサジェスチョン
- 履歴と補完機能によるオートサジェスチョン。 入力中の文字列に対してパス、コマンドオプション、履歴を元にサジェストされる。
- 24bitカラーのサポート
- True color(1677万色)をサポート。
- シンプルでクリーンなスクリプト構文
- モダンなスクリプト構文。
- manページを元にしたコマンド補完
- manページから補完設定を自動生成するため個別の補完設定なしで補完が有効になる。
- 充実したドキュメント
- 分かり易いドキュメントが充実している。シェル上から
help
と打てばブラウザが開きHTMLベースのドキュメントが閲覧できる。
インストール
Homebrewでインストール
$ brew install fish
$ fish -v
fish, version 2.4.0
コンフィグレーション
fishは起動時に以下の優先順位でコンフィグレーションを読み込む。
- 基底コンフィグレーション
- システム共通コンフィグレーション
- 各種コンフィグレーションスニペット
- ユーザ固有コンフィグレーション
基底コンフィグレーション
基底コンフィグレーションはfishに同梱されている編集不要の基礎となるコンフィグレーション。
パスは$__fish_datadir/config.fish
となっており変数$__fish_datadir
の値は、
echo $__fish_datadir
で確認できる。
一般的には/usr/share/fish/config.fish
homebrewの場合は/usr/local/Cellar/fish/2.4.0/share/fish/config.fish
となる。
システム共通コンフィグレーション
システム共通コンフィグレーションはOS内で共通的に利用されるfishコンフィグレーション。
パスは$__fish_sysconfdir/config.fish
となっており変数$__fish_sysconfdir
の値は
echo $__fish_sysconfdir
で確認できる。
一般的には/etc/fish/config.fish
homebrewの場合は/usr/local/Cellar/fish/2.4.0/etc/fish/config.fish
となる。
各種コンフィグレーションスニペット
コンフィグレーションスニペットはファイル拡張子.fish
を持つファイルで以下のディレクトリに配置することができる。
- ユーザ固有コンフィグレーションスニペット (
$XDG_CONFIG_HOME/fish/conf.d
) - システム共通コンフィグレーションスニペット (
$__fish_sysconfdir/conf.d
) - 基底コンフィグレーションスニペット (
$__fish_datadir/conf.d
)
ユーザ固有コンフィグレーション
ユーザ固有コンフィグレーションはユーザ毎のコンフィグレーションでXDG Base Directory Specificationに則りパスは$XDG_CONFIG_HOME/fish/config.fish
となる。
環境変数XDG_CONFIG_HOME
を定義していない場合デフォルトとして~/.config
が適用されるためコンフィグレーションパスは~/.config/fish/config.fish
となる。
基本的な使い方
viモードを有効にする
コマンドラインエディタをviモードにすることができる。
シェル上からfish_vi_key_bindings
関数を実行するとviモードになる。元に戻したい場合はfish_default_key_bindings
関数を実行すれば良い。
ただしfishの標準はemacsモードであるためviモードにすると公式チュートリアルにあるいくつかのキーバインドが効かない状態になる。 本来はデフォルトのemacsキーバインディングを一旦忘れvi的にはどのキーに割り当てるのが自然か考えてみるのが良い気がするが ここでは一旦viモードにデフォルトのキーバインディング取り込んで動作させる。
$XDG_CONFIG_HOME/fish/functions/fish_user_key_bindings.fish
を編集しデフォルトのキーバインディングをviの全モードで利用できるようにする。
function fish_user_key_bindings
for mode in insert default visual
fish_default_key_bindings -M $mode
end
fish_vi_key_bindings --no-erase
end
またこれはviモードとは直接関係無いが公式チュートリアルではMETAキーに ALT を利用している。 iTerm2を利用している場合は ALT をMETAキーとして利用できるようにしておく必要がある。
iTerm2のメニューから Profiels Open Profiles.. Edit Profiles.. Keys Left option key acts as: を +Esc
に設定する。
オートサジェスチョン
オートサジェスチョンは入力中のコマンド、パスに対するサジェスチョンをグレーで表示する。
例えばls
と入力すると以下ように履歴から対象とするサジェストしてくれる。
グレーの部分は未確定の部分であるためこのままリターンキーを押した場合コマンドとして解釈されるのは白字の部分のみとなる。
>ls /var/log
サジェスチョンが表示されている状態で、→ 、または CTRL f キーを押すとサジェスチョンを受け入れグレーから白字に色が変わる。
>ls /var/log
# [→] または [CTRL] [f]キーを押す
>ls /var/log
同様にサジェスチョンが表示されている状態で、ALT → 、または ALT f キーを押すと単語単位にサジェスチョンを受け入れ、受け入れた部分がグレーから白字に色が変わる。
>ls /var/log
# [ALT] [→] または [ALT] [f]キーを押す
>ls /var/log
シンタックスハイライト
入力中のコマンドが存在しない場合は特有の色(例では赤字)で表示される。
>/bin/mkdir
存在する場合は別の色で表示される。(例では白字)
>/bin/mkdir
存在するパスの場合はアンダーラインが引かれる。
# 存在しない場合
>ls /Hoge
# 存在する場合
>ls /Documents
タブ補完
入力中にタブを押すことで補完処理が実施される。
補完対象となるコンテクストには以下がある。
- コマンド(ビルトイン、関数、一般的な外部コマンド)
- シェル変数名
- ファイル名(ワイルドカード付きでもOK)
- ジョブID、ジョブ名、プロセス名
また上記以外にもコンテクストに応じた高度な補完が行われるケースもある。例えばssh
は接続先の補完にknown_hosts
に登録されたホスト名が利用される。
候補が複数ある場合は候補リストが表示される。
候補リスト表示中に TAB 、 ↑ → ↓ ← 、CTRL f 、CTRL b 、CTRL n 、CTRL p で候補を選択できる。
また選択中に文字列を入力するとマッチする候補リストが絞り込まれる。
組み込みコマンド complete を利用することで独自の補完処理を作成することができる。
$__fish_datadir/completions
には多くの独自補完処理のためのスクリプトがあるためこれを参考にすると良い。
シェル変数と環境変数
シェル変数、環境変数ともに set コマンドで定義、削除を行う。
# シェル変数を定義
> set hoge ほげ
> echo $hoge
ほげ
環境変数は-x
オプションを付与することで定義できる。
# 環境変数を定義
set -x FUGA ふが
> echo $FUGA
ふが
定義済みのシェル変数、環境変数は-e
オプションを付与することで削除できる。
# 定義した変数を削除
> set -e hoge FUGA
fishにおける全ての引数はリストで表現される。
setコマンドにおいても PATH のような複数の要素を扱う変数はセパレータ付きの文字列で表現するのではなくリストで扱う。
# リストを作成
> set HOGE hoge1 hoge2 hoge3
> echo $HOGE
hoge1 hoge2 hoge3
# リストに追加
set HOGE $HOGE hoge4 hoge5
> echo $HOGE
hoge1 hoge2 hoge3 hoge4 hoge5
ユニバーサル変数
ユニバーサル変数は特殊変数で以下の二つの特徴がある。
- 共有
- ユニバーサル変数は異なるfishプロセス間で透過的に共有される。宣言と同時に即時に他のfishプロセスから参照できる。
- 永続
- ユニバーサル変数は宣言すると明示的に削除しない限り永続する。fishプロセスを全て終了したり、OSを再起動したりしても失われない。
環境変数は-U
オプションを付与することで定義できる。削除は同じように-e
オプションで行う。
# ユニバーサル変数を定義
set -U EDITOR vim
# ユニバーサル変数を削除
set -e EDITOR
設定を即座に全fishプロセスへ反映させたいような設定に対しては便利そうだが安易にリスト型の値を持つ変数ををユニバーサル化すると消えずに追加され続けるようなバグを生み出してしまいそうだ。
ワイルドカード
通常のワイルドカード*
に加えてサブディレクトリ配下を再帰的に辿る**
が利用できる。
時間が掛かるようなケースで中断したい場合は CTRL c で中断できる。
# HOME直下のjpgファイルをリストアップ
> ls ~/*.jpg
# HOME配下の全てjpgファイルをリストアップ
> ls ~/**.jpg
コマンド履歴の利用
コマンド入力中にCTRL p キーを押すことで入力済みの文字列にマッチする履歴を過去へ向かって検索することができる。 逆にCTRL n キーを押すことで現在へ向かって検索する。
# lsまで入力
>ls /var/log
# [CTRL] [p]キーを押す事でマッチする履歴を表示
>ls /tmp
例えばls
と入力した状態で CTRL p キーを押すと履歴から最も最近のls
が含まれるコマンドが表示される。
終了ステータス
fishでは最後に実行したコマンドの終了ステータスを $status へ格納する。
0が成功で1以上が失敗を意味する。
>cd NONE_EXISTENT_DIR
cd: The directory 'NONE_EXISTENT_DIR' does not exist
>echo $status
1
リダイレクション
標準入力と標準出力へのリダイレクトは他のシェルと同様に < > » だが標準エラーへのリダイレクトは ^ を利用する。
>cd NONE_EXISTENT_DIR ^err.txt
最後に
fish上で生きていくために最低限必要そうな点をまとめてみた。
素の状態で十分実用的なfishではあるがfishermanというプラグインマネージャもあるのでよりカスタマイズしていく場合はこちらを利用すると良さそうだ。