初学者向けに AWS CLI のタブ補完の有効化手順を、かみ砕いて書いてみる（WindowsとLinuxどっちも）

AWS CLIのタブ補完を有効化する手順はドキュメントに記載されていますが、初学者にはちょっと難しそうだなあと思いました
自分の勉強のためにも、コマンドの意味も補足しながらかみ砕いた手順を記載します

※AWS公式ドキュメントでは「コマンド補完」と記載されていますが、個人的には「タブ補完」のほうがなじみあるため、この記事では「タブ補完」と記載します

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-completion.html


# Linuxの場合の手順

## パスにAWSコンプリータがあることを確認（なければ追加）

AWS公式ドキュメントに記載されている以下のコマンドによって、AWSコンプリータがパスにあるかどうかを確認できます
```
$ which aws_completer
/usr/local/bin/aws_completer
```


:::note
- `which`コマンドを使うことで、コマンドの実体がどこにあるのかを調べることができます。要するに、`which <xxxxxx>`と入力してパスが返ってくれば、パスが通っていると言えるのです

- AWSコンプリータとは、`aws`コマンドでタブ補完を行うためのツールのようなものです。
（ツールという表現が正しいかどうかはちょっと怪しいので、あくまでイメージと捉えてください）
:::


もしパスが通っていない場合は、パスに追加する必要があるので以下の手順を踏みます

### AWSコンプリータのファイルを探す
AWS CLIをインストールしていればどこかにAWSコンプリータも保存されているはず（？）なので、迷子の`aws_completer`を探します

公式ドキュメントは「まずはここを探してみなさい」とヒントをくれています
> パッケージマネージャー - pip、yum、brew、および apt-get などのプログラムは通常、AWS コンプリータ (またはシンボリックリンク) を標準のパスの場所にインストールします。
pip を「--user」パラメータを指定せずにを使用した場合、デフォルトのパスは「/usr/local/bin/aws_completer」です。
pip を「--user」パラメータと共に使用した場合デフォルトのパスは「/home/username/.local/bin/aws_completer」です。
バンドルインストーラ - バンドルされたインストーラを使用した場合、デフォルトのパスは「/usr/local/bin/aws_completer」です。


それでも見つからない場合は、ファイル検索で`aws_completer`を探します
先ほどは`which`コマンドを使用しましたが、ファイル検索を行う場合は`find`コマンドを使用します


```
$ find / -name aws_completer
/usr/local/bin/aws_completer
```    

### 使っているシェルが何か確認する

ファイルの場所がわかればパスを通すことができるので、まずは使っているシェルが何かを確認しましょう
```
$ echo $SHELL
/bin/bash
```

プロセスを確認することでも、シェルの特定ができます
```
$ ps
  PID TTY          TIME CMD
 2148 pts/1    00:00:00 bash
 8756 pts/1    00:00:00 ps
```


### AWSコンプリータをパスに追加する

ログインしているユーザーのホームディレクトリ（`/home/ユーザー名`）で、以下のコマンドを実行するとプロファイルスクリプトが確認できます

```
$ ls -a ~/
.  ..  .bash_logout  .bash_profile  .bashrc  Desktop  Documents  Downloads
```
ドキュメントに記載されている例は、Bashを使っている場合の例ですね

:::note
- プロファイルスクリプトとはLinuxにログインする度に実行されるスクリプトのことで、環境変数の定義などを記載するのが一般的。Bashの場合は`.bash_profile`、`.profile`、`.bash_login`が該当する。
:::


プロファイルスクリプトがわかったら、viなどのエディタでプロファイルスクリプトを開き、末尾に以下の文字列を追加します
```
export PATH=/usr/local/bin/:$PATH
※「/usr/local/bin/」の部分は、findで確認したAWSコンプリータのディレクトリパスを入力する
```
これは、もともとある`$PATH`変数に`/usr/local/bin/`というパスを追加するコマンドです

プロファイルスクリプトに追記したらエディタを閉じ、追記内容を反映させます
```
$ source ~/.bash_profile
```

これで`aws_completer`をパスに追加することができました


:::note
- `source`コマンドとは、主にシェルの設定ファイルの内容を反映させる際に使用するコマンドです。同じようなコマンドに`.`コマンドがあります。

    【 source 】コマンド／【 . 】コマンド――シェルの設定を即座に反映させる
    https://atmarkit.itmedia.co.jp/ait/articles/1712/21/news015.html

    sourceコマンドについて詳しくまとめました 【Linuxコマンド集】
    https://eng-entrance.com/linux-command-source
:::



## タブ補完を有効化する
`aws_completer`をパスに追加できれば、タブ補完を有効化するのは簡単です
（シェルの種類によって手順が異なりますが、ここではbashに限って記載します）

まずはホームディレクトリ内にある`.bashrc`をviなどのエディタで開きます
そして、以下の文字列を末尾に追加して上書き保存します
```
complete -C '/usr/local/bin/aws_completer' aws
```

:::note
- `complete`コマンドを使うことで、コマンドをどのように補完するかを定義することができます。上記のコマンドは、`aws`というコマンドを`/usr/local/bin/aws_completer`（AWSコンプリータ）に従って補完することを定義しています。

- `.bashrc`とは`bash`コマンドを実行したときに読み込まれるファイルです。プロファイルスクリプトと似ていますが、読み込まれるタイミングが異なります。
:::


`.bashrc`を書き換えたらシェルを再起動します
新しいターミナルを開いてもいいですし、`source ~/.bashrc`で変更を反映させてもよいと思います

これで晴れてタブ補完が使えるようになります！！

# Windowsの場合の手順
利用するターミナルはPowerShellです

## スクリプトの実行ポリシー変更

公式ドキュメントには記載されていませんが、まず最初にやらなくてはならないことがあります。
**それはスクリプトの実行を有効化することです**

PowerShellは、デフォルトでスクリプトファイルを実行することができない設定になっています
AWS CLIのタブ補完を有効化するためには`$PROFILE`に追記したスクリプトが実行される必要があります。しかし、**デフォルトのままではポリシーに引っかかってしまいエラーになってしまいます。**

なのでまずは、スクリプト実行のポリシーを変更するために`Set-ExecutionPolicy`コマンドを実行します
```
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
```

:::note
- `-Scope`オプションでポリシー変更の対象を選ぶことができます。現在のプロセスのみ、現在のユーザーのみ、すべてのユーザー、どれに対してポリシーの変更を実行するのかを設定します。

- `-ExecutionPolicy`オプションで、何の実行ポリシーを設定するのかを選択できます。`RemoteSigned`は以下のような設定です。

> インターネットからダウンロードしたすべてのスクリプトと構成ファイルが、信頼できる発行元によって署名されている必要があります。Windows サーバー コンピューターの既定の実行ポリシー。


PowerShellでこのシステムではスクリプトの実行が無効になっているため、ファイル hoge.ps1 を読み込むことができません。となったときの対応方法
https://qiita.com/ponsuke0531/items/4629626a3e84bcd9398f

:::

## ユーザープロファイルの存在を確認
ここからは、公式ドキュメントの通り進めていきます
まず、WindowsでAWS CLIのタブ補完を有効にするには、Windows PowerShell のユーザープロファイルにコードを追記する必要があります
なので、まずはユーザープロファイルをメモ帳で開きます

```
PS C:\> Notepad $PROFILE
```

:::note
- ユーザープロファイルとは、Windowsのユーザーごとのデータや設定（デスクトップの画面設定など）のこと。`C:\User\<ユーザー名>`を見るとユーザーの保存データと設定データが確認できる。ここにはユーザーが保存したデータ（ダウンロード、ドキュメントなど）や、ユーザーごとの設定ファイル（`NTUSERS.DAT`という名前のファイル）が保存されている。

- PowerShell用のプロファイルも作成することができ、プロファイルのパスは`$PROFILE`で定義されています。Bashで言うと`.bashrc`のようなファイルですね。

    PowerShellの.bashrc的な設定ファイルこと$Profileについての紹介
    https://qiita.com/smicle/items/0ca4e6ae14ea92000d18

    Windows PowerShell Profiles | Microsoft Learn
    https://learn.microsoft.com/en-us/previous-versions/bb613488(v=vs.85)?redirectedfrom=MSDN

- `Notepad`コマンドはファイルをメモ帳で開くことができるコマンドです。なので、`Notepad $PROFILE`を実行することでPowerShellのプロファイルをメモ帳で開いて編集することができます。
:::


もし`$PROFILE`がない場合には、次のコマンドを実行してユーザープロファイルを作成できます
```
PS C:\> if (!(Test-Path -Path $PROFILE ))
{ New-Item -Type File -Path $PROFILE -Force }
```

:::note
- 上記のコマンドは、まず`Test-Path`で`$PROFILE`が存在するかどうかを確認しています。そして、存在しない場合には`New-Item`で`$PROFILE`を作成します。
:::

## タブ補完を有効化するためのコードをプロファイルに追記
`$PROFILE`を開いたら、以下のコマンドを追記します

```
Register-ArgumentCompleter -Native -CommandName aws -ScriptBlock {
    param($commandName, $wordToComplete, $cursorPosition)
        $env:COMP_LINE=$wordToComplete
        $env:COMP_POINT=$cursorPosition
        aws_completer.exe | ForEach-Object {
            [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
        }
        Remove-Item Env:\COMP_LINE     
        Remove-Item Env:\COMP_POINT  
}
```

:::note
- `Register-ArgumentCompleter`コマンドは、タブ補完機能を新規登録することができるコマンドです。上記のコマンドでは、`aws`コマンドでタブ補完するために実行するスクリプトを`-ScriptBlock`に記載しています。
:::


コードを追記したら上書き保存して、PowerShellを開きなおします。
そうすると、タブ補完が使用できるようになっています！！

ちなみに、PowerShellで補完できるコマンドの一覧を表示するにはCtrl + [Space] を押す必要があります

```
$ aws s[Ctrl + Space]
s3              ses             sqs             sts             swf
s3api           sns             storagegateway  support
```


# 参考資料

手前味噌ですが、AWS CLIタブ補完をWindowsで有効化したときの躓きポイントをまとめた記事を以前書きました

- WindowsでのAWS CLIセットアップ手順、タブ補完の有効化手順と注意点
https://qiita.com/hatahatahata/items/38380f21aa3fff563f6b

そもそもパスって何？って方はこちらを一読いただくことをお勧めします

- Linux入門 ~「パスを通す」とは~
https://qiita.com/Naggi-Goishi/items/2c49ea50602ea80bf015

`.bashrc`と`.bash_profile`の違いについては、このあたりの記事が参考になりそうです

- Bash: .bashrcと.bash_profileの違いを今度こそ理解する
https://techracho.bpsinc.jp/hachi8833/2021_07_08/66396

- .bashrc ｜ 「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典
https://wa3.i-3-i.info/word13649.html

- .bashrc_profile ｜ 「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典
https://wa3.i-3-i.info/word13650.html

- 「.bashrc」と「.bash_profile」の違い ｜ 「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典
https://wa3.i-3-i.info/diff225shell.html