aws s3 ls があるなら aws s3 cat も実行したい、けど無理そうなので aws s3cat で我慢した
S3 オブジェクトの中身をローカルにダウンロードせずに参照したい
コンバンハ、千葉(幸)です。
aws s3 cat を実行したい、そんな風に思ったことはありませんか?つまりは S3 オブジェクトの中身を参照するためにいちいちローカルにダウンロードしたくない、ということです。
例えばこんなふうに aws s3 ls で S3 バケットの中身を参照して……
$ aws s3 ls chibayuki-hoge-hoge/chibayuki/ 2022-02-13 13:17:45 0 2022-02-13 13:19:15 17 test.txt 2022-02-13 13:19:16 17 test2.txt 2022-02-13 13:19:16 17 test3.txt
そのまま aws s3 cat でオブジェクトの中身を表示させたい、ということです。
$ aws s3 cat chibayuki-hoge-hoge/chibayuki/test.txt hello hello hello
できたらいいですよね。aws s3 cp s3://<s3のパス> <ローカルのパス>
でローカルにダウンロードしてからそれを開く、というのはめんどくさいですもんね。
で、近いところまで行けました。aws s3 cat
ではなくaws s3cat
(半角スペースが入らない)で実現しています。
勘のいいみなさんならどうやって実現したらいいかアタリがついたかも知れません。
分からない方のために、どうやって aws s3cat してるんだ というのを書いていきます。
aws s3cat の種明かし
以下を組み合わせて実現しています。
標準出力への S3 オブジェクトのストリーミング
以下のように aws s3 cp においてローカルのパスに-
を指定することでストリーミングできます。
aws s3 cp s3://mybucket/stream.txt -
AWS CLI エイリアス
以下のように AWS CLI エイリアスを設定しています。
[toplevel] s3cat= !f() { aws s3 cp s3://${1} - }; f
AWS CLI での S3 Streaming
繰り返しになりますが、以下コマンドで S3 オブジェクトをローカルの標準出力にストリーミングでダウンロードできます。
aws s3 cp s3://mybucket/stream.txt -
これは AWS CLI のリファレンスにも載っています。
上記のリファレンスは AWS CLI v2 のものですが、v1 でも同じことができます。DevelopersIO でも 2015 年にすでに取り上げられていました。
標準出力に渡されているので、パイプして繋いであげればgunzip
でもgrep
でもjq
でもpbcopy
でも何でもできます。便利ですね。
アップロードでもストリーミングできる
ダウンロードの場合は以下構文でした。
aws s3 cp s3://mybucket/stream.txt -
引数の順番を入れ替えてあげればアップロードもできます。
aws s3 cp - s3://mybucket/stream.txt
以下のようにヒアドキュメントを使ってあげれば複数行の内容も渡せます。
$ cat << EOF | aws s3 cp - s3://chibayuki-hoge-hoge/chibayuki/test4.txt > test > test > test > EOF $ aws s3 cp s3://chibayuki-hoge-hoge/chibayuki/test4.txt - test test test
覚えておくと便利そうですね。
S3 上のオブジェクトをストリーミングでダウンロードして zip してアップロードする、なんてお洒落なコマンド例もドキュメントに載っていました。
aws s3 cp s3://bucket-name/pre - | bzip2 --best | aws s3 cp - s3://bucket-name/key.bz2
AWS CLI エイリアスを使う
ここまでで、 S3 オブジェクトをローカルにダウンロードすることなく中身を参照する方法が分かりました。
とは言えもうちょっとシンプルに実行したいものです。s3://
を毎回書くのはめんどくさい気がしますものね。
と言うことで AWS CLI エイリアスを使います。AWS CLI エイリアスは「頻繁に使用するコマンドやスクリプトを短縮するために AWS CLI で作成できるショートカット」であると説明されています。
そこまで複雑なものではないので、以下を見ればすぐ理解できるかと思います。
AWS CLI エイリアスの前提条件
- AWS CLI がインストール済みであること
- AWS CLI のバージョンが 1.11.24 以上か 2.0.0 以上であること
- bash スクリプトエイリアスを使用する場合は bash 対応ターミナルであること
1.11.24 は 2016 年に登場したバージョンなので、よっぽど古いものでない限りは対応していると思います。
今回わたしは AWS CloudShell で試したのですが、2022年2月15日現在で以下のバージョンでした。
[cloudshell-user@ip-10-0-15-122 ~]$ aws --version aws-cli/2.4.15 Python/3.8.8 Linux/4.14.252-195.483.amzn2.x86_64 exec-env/CloudShell exe/x86_64.amzn.2 prompt/off
AWS CLI エイリアスファイルの作成
以下のファイルを作成し、そこに構文を書いてあげればエイリアスが使用できます。
~/.aws/cli/alias
エイリアスファイルの一行目には以下を記載してあげる必要があります。
[toplevel]
CloudShell であればホームディレクトリで以下を実行してあげればOKです。
$ mkdir -p ~/.aws/cli $ echo '[toplevel]' > ~/.aws/cli/alias
そこに各種エイリアスを追記していきます。
基本的なコマンドエイリアスの構文は以下です。
aliasname = command [--options]
bash スクリプトエイリアスの場合は以下構文です。
aliasname = !f() { script content }; f
今回の aws s3cat では S3 のパスを引数として渡してあげたいので、以下の書き方にしています。
s3cat= !f() { aws s3 cp s3://${1} - }; f
AWS CLI エイリアスでは aws s3 cat は実現できない
例えば以下のようにエイリアスとしてs3 cat
を指定したらどうだ?と思いましたが、うまくいきませんでした。
s3 cat= !f() { aws s3 cp s3://${1} - }; f
上記のエイリアスを設定した状態でaws s3 cat
を実行しても、元々のaws s3
コマンドが優先度高く解釈されるので、サブコマンドがおかしいと怒られるだけでした。
$ aws s3 cat chibayuki-hoge-hoge/test.txt usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters] To see help text, you can run: aws help aws <command> help aws <command> <subcommand> help aws: error: argument subcommand: Invalid choice, valid choices are: ls | website cp | mv rm | sync mb | rb
aws s3_cat
やaws s3-cat
なら実現できましたが、ちょっとイケてない気がしたのでやめました。
aws whoami とかも実行しよう
以下に AWS CLI のデベロッパーチームやコミュニティによって作成された AWS CLI エイリアスの例があります。
aws whoami
でaws sts get-caller-identity
を実行したり、aws list-sgs
でセキュリティグループ一覧を表示したりなど様々なエイリアスが用意されています。
エイリアスの書き方など参考になる部分があるので、普段よく実行するコマンドのエイリアスを用意してみてはいかがでしょうか。
S3 URI はマネジメントコンソールからコピーできる
aws s3cat を使うイメージはついたものの、S3 のパスを打ち込むのはめんどくさい、ということがあるかも知れません。
そんな時にはマネジメントコンソールから S3 URI をコピーしましょう。
上記の例であれば以下がコピーされます。
- 左下のボタンの場合:
s3://chibayuki-hoge-hoge/chibayuki/test.txt
- 右上のボタンの場合:
s3://chibayuki-hoge-hoge/chibayuki/
パスはマネジメントコンソールからチェックして手元で aws s3cat する、という使い方が便利な時があるかも知れません。
ここまでの例では以下のようにs3://
も含めてエイリアスを指定しているので、コピーした内容をそのまま引数として指定すると重複してしまいます。 S3 URI のコピーを多く使用するのであれば、エイリアスからs3://
を削ってあげるといいでしょう。
s3cat= !f() { aws s3 cp s3://${1} - }; f
aws s3 cat もいつか実装されるだろうか
aws s3 cp でのストリーミングでのダウンロードと AWS CLI エイリアスを組み合わせた aws s3cat のご紹介でした。
両者を組み合わせずそれぞれ単独で使用しても便利な機能ですので、ちょっとした時に思い出して使ってみてはいかがでしょうか。
aws s3 コマンドと言えば高レベルコマンドとも呼ばれ S3 API をいい感じにラップしてくれているコマンドです。標準で aws s3 cat を実装してくれる日が来ると嬉しいな、と思っています。
でもまぁ無いなら無いでそこまで困らないな、とも思っています。あるもので戦っていきましょう。
以上、 チバユキ (@batchicchi) がお送りしました。
追記
はてブのコメントで以下の feature request があることを教えてもらいました。aws s3 cat を使いたい人は多いのですね……。