aws cliはサーバ上のcuiでawsを操作できるため、スクリプトに組み込んでawsを自動で操作するのにお手軽で便利。
今回はその中で、s3にあるファイルを一気にダウンロードする方法をメモしておく。
例えば、いろんなホスティングサーバでバックアップを取りたいが、同じサーバ内に置くのはあまり良くないので、awsのs3に置くような運用とする。
バックアップしたいデータは、静的ファイル、DB等など、複数の出たがあり、それらがいつのデータかわかるように、名前に日付を付けてバックアップした場合、該当の日付のファイルを一気にダウンロードしたい場合がある。
そういう時に今回の方法は使える。
今回は、aws cliをすでにセットアップ完了しており、使える状態であることを前提とする。
s3とファイルをやり取りするコマンドは、シェルのcpコマンドに近しいが、それらとは異なる点がある。
ファイルをs3から取得するコマンドは以下。
aws cli s3 s3://(bucket名)/(ダウンロードしたいファイルパス) (ダウンロード先)
今回は、例えばファイル名の頭に「20220618」とついているファイルを一気にダウンロードしたいと思っているが、
aws cli s3 s3://(bucket名)/20220618* (ダウンロード先)
としても、対象のファイルはダウンロードできず、
fatal error: An error occurred (404) when calling the HeadObject operation: Key "*" does not exist
と言われて怒られる。
アスタリスクを使って一気にダウンロードするためには、「–include」「–exclude」「–recursive」の3つのオプションを使う必要がある。
これらのオプションを、コピーコマンドの後ろにつけて、コピーの詳細(どのファイルを対象とするか等)を指定する。
なので、コピーコマンド自体は「このフォルダからこのフォルダにコピーする。対象のファイルはオプションで」という感じ。
(シェルスクリプトのcpは「このファイルをここへコピー」っていう感覚だが、それとちょっと違う感じ。)
–include 指定した文字列を含むファイルを対象とする。文字列は「’」か「”」でくくること。アスタリスクが使える。
–exclude 指定した文字列を含まないファイルを対象とする。 文字列は「’」か「”」でくくること。 アスタリスクが使える。
–recursive 再帰的に処理を行う。
いろんなサイトを見ると、上のようなことが記載されているが、気を付けるべき点がいくつかある。
- includeとexcludeは必ず両方必要。例えば、欲しいのはファイルの頭に「20220618」とついているものだけなので「–include ‘20220618*’」としたいところだが、これだと20220618がついてないファイルも対象となってしまう。なので、かならず「–exclude ‘*’」を付ける必要がある。
- includeとexcludeは右側のものが優先される。なのでファイルを絞り込むためには「–exclude ‘*’ –inlude ‘20220618*’」(まず全ファイルを対象外とし、’20220618*’というファイルを対象とする)となる。
- 今回は同フォルダ内にあるファイルをコピーするので、再帰的処理を行うrecursiveはいらないと思っていたが、このオプションも必要だった。(処理を繰り返す、ということか?それならこのオプションがなくても1ファイルだけでもコピーできるはずだが…。ちょっとわからない。)
上記を踏まえて、一気にファイルをダウンロードするのは以下のようなコマンドとなる。
aws s3 cp s3://(bucket名)/ . --exclude '*' --include '20220618*' --recursive
ちなみに、bucket名の後にフォルダ名をつなげれば、任意の階層を指定できる。
あと、bucket名の最後の「/」はあってもなくてもよい。
あと、もしかしたら、該当のbucketへのアクセス権があるかどうか確認する方法として、一覧表示を出してみたらいい。(一応、リスト表示はできるけどダウンロードはできない、みたいな権限設定もできるが、ほぼこういうことはやらないと思われる)
aws s3 ls s3://(bucket名)