AWS CLI v2 の pager で画面が切り替わる挙動を抑制する
まとめ
- AWS CLI v2 は出力が一定量を超えるとデフォルトで
lessを起動し、ターミナルが全画面の pager 表示に切り替わる - 抑制方法は 3 通り: コマンド単位の
--no-cli-pager、環境変数AWS_PAGER=""、~/.aws/configのcli_pager - 永続化したいなら
.zshenvにexport AWS_PAGER=""を書いておくのが手軽 aws s3 ls | head -5で出るBrokenPipeErrorも、同じ pager 設定で根本解決できる
現象
aws s3 ls s3://some-bucket/ のような一覧系コマンドを叩くと、出力が画面サイズを超えるタイミングで less が起動し、ターミナルが全画面の pager 表示に切り替わる。q を押さないとプロンプトに戻れない。
普通のコマンドは stdout に流して終わるので、勝手に pager に流される挙動は AWS CLI v2 から導入された仕様。AWS CLI v1 ではこの挙動はなかった。
抑制方法
1. コマンド単位(その場限り)
--no-cli-pager フラグを付ける:
aws s3api list-objects-v2 --bucket some-bucket --max-keys 5 --no-cli-pager2. 環境変数(シェルセッション内有効)
AWS_PAGER を空文字に設定する:
export AWS_PAGER=""
aws s3 ls s3://some-bucket/ | head -53. 永続化(~/.aws/config に書き込む)
aws configure set cli_pager ""これで ~/.aws/config の default profile に cli_pager = が書き込まれ、以後すべての aws コマンドで pager が起動しなくなる。
4. シェル設定で永続化(dotfiles を共有している場合に便利)
zsh の .zshenv に追記:
# AWS CLI v2 pager 抑制
export AWS_PAGER="".zshenv はすべてのシェル(ログイン・非ログイン・非インタラクティブを含む)で読まれるため、cron や script からの呼び出しでも有効になる。.zshrc だとインタラクティブシェル限定になる点に注意。
おまけ: head に流したときの BrokenPipeError
aws s3 ls s3://some-bucket/ | head -5
# 出力は正しく取れるが、最後にこのエラーが出る:
# aws: [ERROR]: [Errno 32] Broken pipe
# Exception ignored while flushing sys.stdout:
# BrokenPipeError: [Errno 32] Broken pipeこれは AWS CLI v2 の Python ベースのページネーターが、head がパイプを閉じた後も次ページを送ろうとして発生する既知の挙動。--page-size 5 を指定して取得ページサイズを小さくしても、最初のページ送信中にパイプが閉じれば同じく発生する。
stdout の中身(一覧)は正しく取れているので機能上の問題はないが、エラー表示が目障りな場合は以下で対処できる:
2>/dev/nullで stderr を捨てるAWS_PAGER=""を設定する(pager 経由でなくなるので根本解決)aws s3api list-objects-v2 --max-keys 5のように API レベルで件数を絞る(追加ページ送信が発生しないので Broken pipe が出ない)
ただし aws s3api に切り替えると出力フォーマットが API 寄りの ISO 8601 + タブ区切りに変わり、aws s3 ls のローカルタイムゾーン表示と揃わない点には注意。表示形式を維持したいなら AWS_PAGER="" を入れた上で aws s3 ls ... | head -5 を使うのが素直。
設定が効いているかの確認
現在のシェルセッションで pager 設定が効いているかは、以下で確認できる:
echo "[$AWS_PAGER]"
# → [] が表示されれば AWS_PAGER="" が効いている
aws configure get cli_pager
# → 空文字が表示されれば cli_pager = が ~/.aws/config に書かれている優先順位は 環境変数 AWS_PAGER が ~/.aws/config の cli_pager より上。両方設定する必要はなく、どちらか一方で十分。