blog.syfm

徒然なるままに考えていることなどを書いていくブログ

任意のコマンドのサブコマンドにエイリアスを設定できる salias をつくった

動機

最近のコマンドは大抵サブコマンド形式になっています。

$ docker pull hello-world

このように、コマンド名 + サブコマンド + 対象 みたいな形式。
サブコマンドには大きく2種類あって、サブコマンドに動詞を指定するタイプと、リソースを指定するタイプがあります。
感覚的に、コマンドのパターンが多くなってくるとリソースを指定するタイプが主流になっている気がします。
最近だと Docker が以下のように動詞タイプからリソースタイプに移行しつつあるようです (現在はどちらのコマンドも利用できる)

$ docker run hello-world
# 動詞タイプ

$ docker container run hello-world
# リソースタイプ

動詞タイプのほうがタイプ数は少ないが、リソースタイプのほうが階層化されているので秩序がある。
とはいえ、割りと頻繁に利用するコマンドなのに、毎回 container とタイプするのはかなり面倒。
alias を使って、

$ alias dc='docker container'

みたいなこともできるけど、なんとなく気持ち悪いし、既存のコマンドと衝突する可能性も十分にあります。特にすべてのエイリアスがフラットになっているので管理が煩雑になるのも厳しいところです。

つくったもの

このため、サブコマンドにエイリアスを設定できるツールをつくりました。

github.com

これを利用すると、TOML の設定ファイルにサブコマンドに対するエイリアスをコマンドごとに設定できます。

[go]
i = "install"
b = "build"

[docker]
l = "logs"
i = "image"
c = "container"
cl = "container ls"

[kubectl]
c = "create"

利用するには、以下のコマンドを実行する必要があります。

$ source <(salias __init__)

毎回実行するのは面倒なので、.zshrc.bashrc などに含めておくことをおすすめします。
こうすると、以下のように実行できるようになります。

$ docker c ls
# docker container ls

コマンド自体にエイリアスを設定することももちろんできるので、以下のようにもできます。

$ alias d='docker'
$ d c ls
# docker container ls

仕組み

仕組みは単純で、source <(salias __init__) で alias を列挙したテキストをプロセス置換でカレントシェルに読み込ませています。
例えば上の例だと、salias __init__ は以下のような結果を返します。

alias go='salias go'
alias docker='salias docker'
alias kubectl='salias kubectl'

これをプロセス置換で source することで、各コマンドが salias を通して実行されるようになっています。

salias は、引数に渡されたコマンドを展開し、実行しています。

まとめ

目標としていたのは、サブコマンドのタイプ量を極力減らす・エイリアスが大量に増えることを防ぐことだったので、サブコマンドのみエイリアスを設定できるようにしています。
また、Zsh の alias でできるようなグローバルエイリアスも機能に加えたかったのですが、すべてのコマンドを salias に通さないといけなく色々大変そうだったため、今回はひとまず見送りました。
salias を利用して一文字でもタイプ数が少なくできれば幸いです。

その他

土曜にこれを実装していて、PlaidCTF があることを完全に忘れていた。
ちゃんとやっていた友人の Writeup は以下。

ywkw1717.hatenablog.com