【AWS】S3のファイルをローカルPCに同期したい【aws-cli】

## やりたいこと

S3の画像（ファイル）をローカルPC(ubuntu18.04)に同期したい。

## 環境

- OS: ubuntu18.04
- aws-cli version: 1.18.175
- python3.6.9

```
$ aws --version
aws-cli/1.18.175 Python/3.6.9 Linux/5.4.0-56-generic botocore/1.19.15
```


## `aws-cli`のインストール

※以下では環境変数を`export`コマンドで設定しているが、毎回やる必要があるため面倒な場合には`~/.bashrc`などに設定する。

### pipでaws-cliインストールする

`aws`コマンドを使用する。
`aws`コマンドは`aws-cli`をインストールすると使用できるようになる。


ここでは`pip`コマンドにてインストールする方法を記しておく。

```bash
$ pip3 install awscli --upgrade --user
# 必要に応じて以下のコマンドでawsコマンドのpathを通す
$ export PATH=~/.local/bin:$PATH
```

参考： [Linux での AWS CLI バージョン 1 のインストール、更新、アンインストール - pip を使用した AWS CLI バージョン 1 のインストールとアンインストール](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-linux.html#install-linux-awscli)

※他インストール方法についてはここでは割愛するが、参考にさせていただいた記事では他の方法も紹介されている。


以下のコマンドでインストールできたことを確認する。

```
$ aws --version
aws-cli/1.18.175 Python/3.6.9 Linux/5.4.0-56-generic botocore/1.19.15
```

※ 今はversion1と互換性の無いversion2が出ているよう。ただし以下の記述をみるとAWS 1のサポートが切れるわけではないので、今回は困らない限りこのまま書く。
> AWS CLI バージョン 1 はオリジナルの AWS CLI であり、このサポートは継続されます。ただし、AWS CLI バージョン 2 で導入された主な新機能は、AWS CLI バージョン 1 にバックポートされない場合があります。

引用：[AWS CLI のインストール](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-install.html#cli-chap-install-v1)

### AWSの資格情報を設定する

awsコマンドでAWSへのアクセスをするための設定する。

様々な方法があるが、ここでは環境変数でアクセスキーとシークレットキーを設定する。

以下のコマンドで環境変数に資格情報を設定する。

```
$ export AWS_ACCESS_KEY_ID=<自分のアクセスキー>
$ export AWS_SECRET_ACCESS_KEY=<自分のシークレットキー>
```
参考：[AWS CLI の設定 - AWS CLI を設定する環境変数](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-envvars.html)


※その他の方法や詳細については[AWS CLI の設定](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-configure.html)にて

---

## S3の画像を同期する

※ pathなどは問題の無い程度に置換済み

### `aws s3 sync`コマンド


基本的な公文は以下です。

```bash
$ aws s3 sync <source> <target> [--options]
```

> s3 sync コマンドはバケットとディレクトリの内容を同期します。または 2 つのバケットの内容を同期します。通常、s3 sync は欠落しているか古くなったファイルやオブジェクトを、ソースとターゲットの間でコピーします。

引用：[AWS CLI での高レベル (S3) コマンドの使用 - オブジェクトの同期](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-sync)


今回は`aws s3 sync`コマンドを用いてs3バケットとローカルのディレクトリを同期させるため、そのように例を書いていく。


#### 基本的な使い方

```
$ aws s3 sync s3:<Buket名> <local path>
```

`$ aws s3 sync s3://example.jp/ ./`

`example.jp`というバケットの`/test/`下の画像を`./`下に同期する。

```bash
$ aws s3 sync s3://example.jp/ ./
download: s3://example.jp/img.png to ./img.png
download: s3://example.jp/test/img.png to test/sample.png
download: s3://example.jp/test/img.png to test/sample.jpg
```

#### S3のpathを指定して同期

`$ aws s3 sync s3://example.jp/test/ ./`

`example.jp`というバケットの`/test/`下の画像を`./`下に同期する。

```bash
$ aws s3 sync s3:/example.jp/test/ ./
download: s3://example.jp/test/sample.png to ./sample.png
download: s3://example.jp/test/sample.jpg to ./sample.jpg
```

#### `--exclude`,`--include`などのオプションでファイルをフィルタする

`$ aws s3 sync s3://example.jp/test/ ./ --exclude "*" --include "*.png"`

`example.jp`というバケットの`test/`下から`.png`で終わるファイルのみをフィルタして`./`下に同期する。

```bash
$ aws s3 sync s3://example.jp/test/ ./ --exclude "*" --include "*.png"
download: s3://example.jp/test/sample.png to ./sample.png
```

##### `--include`のみでは意図したとおりに動作しないため注意

以下のように`--include`のみの指定では全て取ってきてしまうよう。
あくまで`--exclude`で除外したものに対しての`--include`オプションであるためらしい。

参考：[AWS CLI の S3コマンド の include オプションには注意が必要](https://qiita.com/fantasista_21jp/items/2addf3ff81950b2d512a)

```bash
$ aws s3 sync s3://example.jp/test/ ./ --include "*.png"
download: s3://example.jp/test/sample.png to ./sample.png
download: s3://example.jp/test/sample.jpg to ./sample.jpg
```

上記の例では`--exclude "*"`で全てのファイルを除外して、`--include "*.png"`で全ての中から`.png`で終わるファイルのみを同期している。

[公式のサンプル](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-sync)には上記のような例も乗っているが注意。


### その他のオプションなど

ここではごく一部のみ紹介。

- `--exclude <val>`:`<val>`をファイル名に含むファイルを除外する
- `--include <val>`:`<val>`をファイル名に含むファイルを対象に含める
- `--delete`:ソース（今回はS3内）に存在しないファイルまたはオブジェクトをターゲット（今回はローカルPC）から削除する

この他のオプションや詳細については以下を参考に。
参考：
- [AWS CLI での高レベル (S3) コマンドの使用 - オブジェクトの同期](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-sync)
- [AWS CLI Command Reference - sync] (https://docs.aws.amazon.com/cli/latest/reference/s3/sync.html)

---

## 参考にさせていただいた記事やリファレンスなど

ありがとうございます！

- [AWS CLI の S3コマンド の include オプションには注意が必要](https://qiita.com/fantasista_21jp/items/2addf3ff81950b2d512a)

- [Linux での AWS CLI バージョン 1 のインストール、更新、アンインストール](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-linux.html)

- [AWS CLI での高レベル (S3) コマンドの使用 - オブジェクトの同期](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-sync)

- [AWS CLI Command Reference - sync] (https://docs.aws.amazon.com/cli/latest/reference/s3/sync.html)