🐟

fish shellでbatとezaを自動切り替えする関数 bate を実装

2024/03/17に公開

結論

> functions detail bate

# Defined via `source`
function bate
    if test -d $argv
        eza $argv
    else
        bat $argv
    end
end

解説

なぜ作るのか?

batコマンドはRust製のcatツールです。
https://github.com/sharkdp/bat

このbatツールはファイルを指定したらファイルを開きますが、ディレクトリを指定した場合はエラーになります(この挙動はcatコマンドと同じです)

batの実行例
# ファイルを指定したらそのままファイルの中身を出力
> echo 'hoge' > hoge.txt
> bat -p hoge.txt # (-p はプレーンテキスト出力)
hoge

# ディレクトリを指定したらエラーを出力
> mkdir dir1
> bat dir1
[bat error]: 'dir1' is a directory.

このエラーが出た時、ほぼ毎度手動でディレクトリの中身を出力してファイルを探し直しています。
そこで、ディレクトリを指定してしまった時はそのディレクトリの中を出力するようにしたいです。

ディレクトリの中身を表示するのは eza コマンドというRust製のlsツールで行います。
https://github.com/eza-community/eza

ezaの実行例
> eza -T # (-T はツリー表示のオプション)
.
├── dir1
└── hoge.txt

fishで関数を作成

fish では 関数を function コマンドで定義します。
https://fishshell.com/docs/current/cmds/function.html

> function [option] NAME; BODY; end;

引数の扱い

コマンドの引数は $argv という変数に格納されます。

条件判定 & 分岐

fishは test コマンド で判定を行います。
https://fishshell.com/docs/current/cmds/test.html

test コマンドは条件に従って引数を判定し、その判定結果が正しければ終了ステータスに 0 を、正しくなければ 1 を格納します。
コマンドの終了ステータスは $status に格納されます。

パスの中身がファイルかディレクトリかを判定するには、 -d でディレクトリかどうかを判定します。

> test -d hoge.txt 
> echo $status
1 # hoge.txtはディレクトリではないため 1
> test -e hoge.txt # -e でファイルが存在するかどうかを判定する
> echo $status
0 # hoge.txt は存在するため正しくて 0

分岐には if コマンド で分岐します。
https://fishshell.com/docs/current/cmds/if.html

if コマンドは 終了ステータスによって処理を分岐させます。
書き方はよくある if ~ else と同じです。

> if test -e hoge.txt
>   echo 'It is true!'
> else
>   echo 'It is false!'
> end
> It is true!

関数を作成

上記のことを踏まえてfish shellに関数を定義します。

> function bate
    if test -d $argv
        eza $argv
    else
        bat $argv
    end
end
> funcsave bate # funcsave を実行しないとファイルに出力されないため注意
funcsave: wrote /Users/XXXXXX/.config/fish/functions/bate.fish

Discussion