良く使うコマンドをファイルで管理する

Posted by rhoboro on 2021-07-22

タイトルの件、良い感じに解決できたので方法をメモ。

やりたいこと

普段の業務では複数のプロジェクト(リポジトリ)を切り替えながら開発をしています。

それぞれのプロジェクトは、Makefileを使っていたり、スクリプトを用意していたり、docker-composeコマンドを多用していたりと良く使うコマンドが違います。 プロジェクトの切り替え頻度も頻繁なものからやたまにしか触らないものまで様々です。

また、共有のEC2インスタンスへの接続に下記のようなワンライナーを使ったり、データベースやユーザ指定でコマンドを実行し、サービスごとのデータベースに接続したりもしています。

$ aws ssm start-session --target $(aws ec2 describe-instances --filters "Name=tag:Name,Values=<INSTANCE NAME>" | jq -r '.Reservations[].Instances[].InstanceId')

前々からこのようなケースでのコマンド入力を楽にしたいと考えていました。 久々のプロジェクトではコマンドを探したり、思い出すことにも地味に時間がかかります。

ただ、これまで下記のように上手い方法が見つからずにいました。

  • メモしておく
    • メモの管理や検索が必要だったり、ファイルを開いてコピーする必要がある
  • コマンドエイリアス機能
    • 引数を1つだけ変えたものを大量に登録するなどには向かない
  • コマンド履歴機能
    • 便利なので多用しているが、少し時間があくと履歴が消えてしまう
  • Makefile
    • 個人的なコマンドも含むため、個別に.gitignoreに登録しないといけない
  • スニペットアプリ
    • エイリアスと同じく少し違うコマンドを大量に登録するのには向かない

上記のほか、コマンド履歴にファイルから追加できないかとかも考えましたが、これも履歴ファイルを作るのが面倒だったのでやめました(笑)

ちなみに、わたしは普段スニペットの管理にAlfredを使っています。 Alfredではスニペット内に{cursor}を書くことで展開時のカーソル位置を指定できますが、インスタンス名のような指定するものが限られている(だけど、何台かある)場合は、コマンド実行のたびに入力するのは面倒です。

解決策

先日、この悩みをつぶやいていたときにふと解決策を思いつきました。 その解決策は、良く使うコマンドをファイルに書いておき、それをpecoで絞り込むというものです。 具体的には、次のスニペットを.zshrcに書き足しました。

# peco-cmd
bindkey '^Y' peco-cmd
function peco-cmd() {
  local cmd=$(find ${HOME}/commands -type f -not -name "_*" | xargs /bin/cat | peco --query "$LBUFFER")
  if [ -n "$cmd" ]; then
    BUFFER="$cmd"
    zle accept-line
  fi
  zle -R -c
}
zle -N peco-cmd

これは書籍みんなのGo言語で知り、普段から愛用させてもらっているpeco-srcを参考にしています。

このスニペットを書いた.zshrcを読み込み、~/commands内に1行1コマンドで書いたファイルを用意しておくと、Ctrl+Yでpecoが起動し、絞り込んで選択したコマンドをすぐに実行できます。 ファイルはプロジェクトごとに分けて管理でき、ただのテキストファイルなので編集も簡単で、優先度も記載順なので直感的です。 また、不要になった際はファイル名の先頭に_をつけるだけで除外できます。

下記は実際に動かしているデモ動画です。

peco-cmd

結構いい感じに効率化できました。 たまにしか使わないコマンドを非表示にしながら残しておけるのも地味に便利です。

ちなみに複数行対応はしてないのですが、複数行のコマンドの場合はAPIのリクエストパラメータのように実行時に変更したい箇所がでてきそうなので、また別の管理方法が必要かなと思ってます。

tags: peco, shell