[小ネタ] AWS_PROFILE を簡単に設定する自作 TAB 補完ツール aws-profiler を Zsh に対応させてみた [おまけ有り]

普段使いのシェル環境を BASH から Zsh に乗り換えたのですが、その際拙作の AWS_PROFILE 設定支援ツールを Zsh でも動くように変更しました。そのご案内と、BASHからZshへ環境を移す方向けにいくつかメモを共有します。
2019.12.30

TL;DR

  • Zsh の TAB 補完自作も全然難しくない
  • さらに簡単にすます方法もある(bashcompinit
  • Zsh 初心者向けのおまけもあり

はじめに

みなさん、BASH 使ってますか!(挨拶

ぼくもこの 10 月までは BASH が普段使いのシェル環境だったのですが、仕事の macOS を Catalina にしたことを機に Zsh に乗り換えました。何せ macOS Catalina のデフォルトシェルが Zsh に変更になったということで、今後 Apple からの BASH へのサポートが不安になるからです。

といいつつ、実は以前から Zsh への乗り換えは気になってはいたものの、特に↓のような作り込んだ BASH 環境があったため二の足を踏んでいました。特に TAB 補完のところが BASH と Zsh で実装が異なると思っていたからです。

ところが調べてみると、Zsh の TAB 補完もそんなに複雑ではなく BASH から簡単に持ってこられることが分かりました。移植の過程で得られた(わずかばかりの)知見をここで共有したいと思います。

移植版

すでに Gist のほうに公開しています。

BASH と共通で使えるようにしてあるのでファイル名が「.bash_profile_aws-profile」のままなのですが、気に入らなければ変更して頂いて構いませんw
導入方法も BASH のときと同じで、依存しているツール(fzfhighlightと Ruby、AWS CLI)をインストールした上で、下記をお使いの .zshrc に追記してください。

# autoload -U compinit && compinit
if [ -f ~/.bash_profile_aws-profile ]; then
        . ~/.bash_profile_aws-profile zsh
fi

なお 3 行目の末尾に zsh と書いてありますが、実はこれは必須ではなく、通常はシェル固有の環境変数(BASHならびにZSH_NAME)をみて動作を変更しています。
また注意点としては、1 行目にコメントアウトしてあるように compinit モジュールの読み込み後に実行するようにしてください。Zsh を使っていて compinit していないひとは極少数派なのでは? と勝手に思っているのですが、必要であればこれも実行するようにコメントを外してください。

使い方

BASH 版と同じですので割愛します。

簡単な解説

移植にあたって追加したのは、大きく二ヶ所です。

  • Zsh 用に _aws-profile 関数を用意
    • compdef 命令にて aws-profile コマンドの補完時にはそちらを呼び出す
    • 補完候補は BASH 版と同じくlist-aws-profileを呼び出して、その内容を _arguments として返す
  • unset-aws-profile関数内にて関連する環境変数をリセット(unset)する際evalするようにした

1 番目は、普通に Zsh 対応です。
Zsh は BASH のような complete 命令をつかうのではなく、独自に関数を用意してそちらを呼び出す方式のようですので、それにならいました。もちろん bashcompinit という、BASH 互換の complete を Zsh で使えるようにするモジュールもあってそれも試したのですが、Zsh 風に書き直すのもたいした手間ではないと気付いたのでこうしています。

2 番目は BASH と Zsh の非互換性を吸収するためです。Zsh はデフォルトの場合、ひとつの変数にはいっていた文字列は空白で区切って評価することなく、ひとつの連続した文字列として扱うためです。
sh_word_split をセット(setopt)する選択肢もあったのですが、全体のシェルの動作を変更してしまいますので、多少ワークアラウンド的ではありますが局所的に対応できるこちらの方法を採用しています。

まとめ

環境のカスタマイズは諸刃の剣です。あまりゴリゴリにカスタマイズするとロックインされてしまい、今回のような環境移動に余計なコストがかかってしまいます。
それでも普段、ストレスを感じながら作業をするのは、ぼくは得策ではないと思っています。さらに新しい環境へ移す段階で機能の取捨選択ができたり、実装上の違いから設計思想に考えを馳せられたりと、心理的なメリットは豊富です。

年も改まることですし、この機会にみなさんも新しい環境に挑戦してみるのはいかがでしょうか。

おまけ 1 : pyenv 環境に AWS CLI の TAB 補完設定をする

AWS CLI を pyenv 環境で使う場合、TAB 補完設定は下記のようにする必要があります。公式ドキュメントどおりではなく、個人的に解法を見つけるのに苦労したのでここに記載しておきます。

if pyenv which aws_zsh_completer.sh 1>/dev/null 2>&1; then
  source "$(pyenv which aws_zsh_completer.sh)"
fi

おまけ 2 : オススメの Zsh サポートツール

多分に趣味がはいりますが、Zsh 環境向けに Homebrew で以下のツールを導入しました。適度に視認性・操作性があがりつつ、かつそこまで重くならないということで重宝しています。

参考

Zsh 初心者が BASH から環境移行するにあたって、以下の URL 先を参考にさせて頂きました。この場を借りてお礼申し上げつつ、今後 Zsh へ環境移行する方々のためにここに列挙させていただきます。