AWS CLI で使い分けよう！S3の高レベルコマンドと API コマンドの違いと適切な選択方法

## 概要
AWS CLI でS3を操作する際、`aws s3` で始まる高レベルコマンドと `aws s3api` で始まる API コマンドの2種類があります。この記事では、それぞれのコマンド体系の違い、特徴、容量制限の違いなどを解説し、状況に応じた適切なコマンド選択方法を紹介します。「なぜ単純な cp コマンドだけでは不十分なのか」という疑問にも答え、効率的な S3 操作のためのノウハウをお伝えします。

## 目次
1. AWS CLI における S3 コマンドの種類
2. 高レベルコマンドと API コマンドの基本的な違い
3. 高レベルコマンドならではの機能と容量制限
4. 具体的なコマンド比較例
5. どのような場合に高レベルコマンドを使うべきか
6. どのような場合に API コマンドを使うべきか
7. 実践的なシナリオと推奨コマンド
8. よくある間違いと注意点
9. 終わりに

## 1. AWS CLI における S3 コマンドの種類

AWS CLI を使用して Amazon S3 を操作する場合、主に2種類のコマンド体系があります。

### 高レベル S3 コマンド（aws s3）

高レベル S3 コマンドは、`aws s3` で始まるコマンド群です。AWS CLI のドキュメントによると、これらは「ファイルを Amazon S3 との間で転送するための、日常的な基本操作に最適化されたコマンド」として設計されています。

```bash
# 高レベルコマンドの例
aws s3 cp myfile.txt s3://mybucket/
aws s3 ls s3://mybucket/
aws s3 rm s3://mybucket/myfile.txt
```

AWS公式ドキュメント（https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-services-s3-commands.html ）によると、高レベルコマンドは使い慣れた Linux/Unix コマンドに似た形式で設計されており、直感的に使用できるように工夫されています。

### API ベース S3 コマンド（aws s3api）

一方、`aws s3api` で始まるコマンドは、Amazon S3 の API を直接マッピングしたコマンド群です。S3 API のすべての機能に直接アクセスできる反面、コマンド構文がやや複雑になります。

```bash
# APIコマンドの例
aws s3api put-object --bucket mybucket --key myfile.txt --body myfile.txt
aws s3api list-objects-v2 --bucket mybucket
aws s3api delete-object --bucket mybucket --key myfile.txt
```

AWS CLI リファレンス（https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html ）によると、s3api コマンドは S3 の API 操作に 1 対 1 で対応しており、REST API で提供されるすべての機能にアクセスできます。

ご指摘ありがとうございます。高レベルコマンドとAPIコマンドの基本的な違いの表を、より多くのコマンド例を加えて拡充します。以下に修正したセクションをお示しします。

## 2. 高レベルコマンドと API コマンドの基本的な違い

### 構文と使用方法の違い

高レベルコマンドは、Linux/Unix のコマンドに似た直感的な構文を持っています。一方、API コマンドは AWS API の構造をそのまま反映した形式になっています。

以下に両者の違いを表で比較します：

| 特徴 | 高レベルコマンド (aws s3) | API コマンド (aws s3api) |
|------|-------------------------|------------------------|
| 構文 | Linuxコマンドに類似 | AWS API 構造に基づく |
| 引数指定 | 位置ベース | 名前付き引数 (--bucket など) |
| 学習難易度 | 比較的容易 | やや複雑 |

### 代表的なコマンド対応表

AWS公式ドキュメント（https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-services-s3-commands.html および https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html を参照）に基づき、一般的なS3操作における両コマンド体系の対応を以下にまとめます：

| 操作内容 | 高レベルコマンド (aws s3) | API コマンド (aws s3api) |
|---------|-------------------------|------------------------|
| ファイルのアップロード | `aws s3 cp file.txt s3://bucket/` | `aws s3api put-object --bucket bucket --key file.txt --body file.txt` |
| ファイルのダウンロード | `aws s3 cp s3://bucket/file.txt ./` | `aws s3api get-object --bucket bucket --key file.txt file.txt` |
| オブジェクト一覧取得 | `aws s3 ls s3://bucket/` | `aws s3api list-objects-v2 --bucket bucket` |
| オブジェクト削除 | `aws s3 rm s3://bucket/file.txt` | `aws s3api delete-object --bucket bucket --key file.txt` |
| ディレクトリ再帰的コピー | `aws s3 cp localdir/ s3://bucket/prefix/ --recursive` | *単一API呼び出しでは不可能（複数のlist-objectsとput-objectの組み合わせが必要）* |
| バケット作成 | `aws s3 mb s3://bucket` | `aws s3api create-bucket --bucket bucket` |
| バケット削除 | `aws s3 rb s3://bucket` | `aws s3api delete-bucket --bucket bucket` |
| ディレクトリ同期 | `aws s3 sync localdir/ s3://bucket/prefix/` | *単一API呼び出しでは不可能（複数のAPIコールの組み合わせが必要）* |
| ACL設定 | `aws s3 cp file.txt s3://bucket/ --acl public-read` | `aws s3api put-object --bucket bucket --key file.txt --body file.txt --acl public-read` |
| バケットポリシー取得 | *高レベルコマンドでは直接対応するものがない* | `aws s3api get-bucket-policy --bucket bucket` |
| バケットライフサイクル設定 | *高レベルコマンドでは直接対応するものがない* | `aws s3api get-bucket-lifecycle-configuration --bucket bucket` |
| ウェブサイト設定 | *高レベルコマンドでは直接対応するものがない* | `aws s3api put-bucket-website --bucket bucket --website-configuration file://website.json` |

この表からもわかるように、高レベルコマンドは日常的なファイル操作に特化している一方、APIコマンドはS3の詳細な設定や管理機能にもアクセスできる特徴があります。

### 内部処理の違い

両コマンド体系の最も重要な違いは、内部処理にあります。AWS公式ドキュメント（https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-services-s3-commands.html より引用）によると：

> S3 コマンドは、複数のAPI操作を実行することがあります。例えば、`aws s3 cp localdir s3://bucket/prefix --recursive` を実行すると、コマンドは`list`を再帰的に呼び出し、`put`オペレーションを各オブジェクトに対して実行します。

一方、API コマンドは、単一の API 呼び出しのみを行います。このため、高レベルコマンドは多くの最適化が自動的に行われますが、API コマンドはより細かい制御が可能になります。

はい、もちろんです。第3章も第2章と同様の観点で修正します。より詳細な情報と具体例を加えた改訂版を作成します。

## 3. 高レベルコマンドならではの機能と容量制限

高レベルコマンドには、S3 API を直接操作するAPIコマンドにはない、多くの便利な機能が自動的に組み込まれています。ここでは、それらの特徴と容量制限の違いについて詳しく解説します。

### 容量制限の違い

AWS公式ドキュメント（https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-services-s3-commands.html を参照）によると、高レベルコマンドとAPI コマンドには以下のような容量制限の違いがあります：

| 機能 | 高レベルコマンド (aws s3) | API コマンド (aws s3api) |
|-----|------------------------|------------------------|
| アップロード容量上限 | 5TB | 5GB (put-object) |
| マルチパートアップロード | 自動対応 | 手動設定が必要 |
| 自動分割・再結合 | あり | なし |
| チャンクサイズの自動調整 | あり | 手動設定が必要 |
| 転送の再開機能 | あり | 手動実装が必要 |
| ファイルチェックサム検証 | 自動 | 手動実装が必要 |

特に重要な点として、S3 API の put-object 操作では単一リクエストでアップロードできるファイルサイズは 5GB が上限ですが、高レベルコマンドの `aws s3 cp` では自動的にマルチパートアップロードを活用して最大 5TB までのファイルを転送できます。

### 高レベルコマンドの自動最適化機能

高レベルコマンドには、日常的なファイル操作を効率化するための様々な自動最適化機能が組み込まれています。AWS公式ドキュメント（https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-services-s3-commands.html を参照）に基づき、主な機能を紹介します：

#### 1. 自動マルチパートアップロード/ダウンロード

大きなファイルを自動的に複数の部分に分割してアップロードし、必要に応じて再結合します。デフォルトでは8MB以上のファイルに対して自動的に適用されます。

```bash
# 10GBの大容量ファイルも簡単にアップロード
aws s3 cp huge_file.tar.gz s3://mybucket/

# チャンクサイズとマルチパート閾値の調整も可能
aws s3 cp huge_file.tar.gz s3://mybucket/ \
  --multipart-threshold 128MB \
  --multipart-chunksize 64MB
```

一方、APIコマンドでは以下のように複数のステップが必要です：

```bash
# 1. マルチパートアップロードの開始
upload_id=$(aws s3api create-multipart-upload \
  --bucket mybucket \
  --key huge_file.tar.gz \
  --query 'UploadId' --output text)

# 2. 各部分のアップロード（分割が必要）
aws s3api upload-part \
  --bucket mybucket \
  --key huge_file.tar.gz \
  --part-number 1 \
  --body part1 \
  --upload-id $upload_id

# 3. 残りの部分も同様にアップロード...

# 4. マルチパートアップロードの完了
aws s3api complete-multipart-upload \
  --bucket mybucket \
  --key huge_file.tar.gz \
  --upload-id $upload_id \
  --multipart-upload file://parts.json
```

#### 2. 並列処理の自動最適化

高レベルコマンドでは、複数ファイルの転送やマルチパートアップロードの各部分を自動的に並列処理します。これにより、特に多数のファイルや大容量ファイルの転送時にパフォーマンスが大幅に向上します。

```bash
# 大量のファイルを効率的に転送
aws s3 cp ./images/ s3://mybucket/images/ --recursive

# 並列転送数の調整も可能
aws s3 cp ./images/ s3://mybucket/images/ --recursive \
  --cli-config-file ~/.aws/custom-config
```

設定ファイル（~/.aws/custom-config）の例：
```
[profile default]
s3 =
  max_concurrent_requests = 20
  max_queue_size = 10000
```

APIコマンドでは、このような並列処理を実現するには、独自のスクリプトやツールを使用して並列実行を管理する必要があります。

#### 3. 再試行とチェックポイント機能

転送が中断された場合に自動的に再試行し、すでに転送済みの部分からの再開が可能です。特にネットワーク環境が不安定な状況でも、高い信頼性でファイル転送を完了できます。

```bash
# 不安定なネットワーク環境でも信頼性の高い転送が可能
aws s3 cp large_dataset.zip s3://mybucket/ \
  --expected-size 15728640000
```

APIコマンドでは、このような再試行ロジックやチェックポイント機能を実装するには、かなり複雑なエラーハンドリングとステート管理が必要になります。

#### 4. 再帰的な処理

`--recursive` オプションを使用することで、ディレクトリ構造全体を簡単に処理できます。

```bash
# ディレクトリ構造を維持したままコピー
aws s3 cp ./project/ s3://mybucket/backup/ --recursive

# 特定のファイルタイプを除外
aws s3 cp ./project/ s3://mybucket/backup/ --recursive \
  --exclude "*.log" --exclude "*.tmp"

# 特定のファイルタイプのみを含める
aws s3 cp ./project/ s3://mybucket/backup/ --recursive \
  --include "*.jpg" --include "*.png"
```

APIコマンドでこれと同等の処理を行うには、ローカルディレクトリをまず走査し、各ファイルに対して個別にput-objectを実行する必要があります。

#### 5. 同期機能

`aws s3 sync` コマンドを使うと、ローカルとS3バケット間で変更されたファイルのみを転送できます。これにより、大規模なデータセットでも効率的に同期できます。

```bash
# 変更されたファイルのみを転送
aws s3 sync ./website/ s3://mybucket/public/

# 削除されたファイルも反映
aws s3 sync ./website/ s3://mybucket/public/ --delete

# 特定の条件でフィルタリング
aws s3 sync ./website/ s3://mybucket/public/ \
  --exclude "*.bak" --include "*.html"
```

AWS公式ドキュメント（https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-services-s3-commands.html を参照）によると、syncコマンドはファイルサイズとタイムスタンプを使用して変更を検出します。APIコマンドにはこのような同期機能がないため、独自にファイル比較ロジックを実装する必要があります。

#### 6. その他の最適化機能

**サイズ依存の転送戦略：**
高レベルコマンドは、ファイルサイズに応じて最適な転送戦略を自動的に選択します。小さなファイルは単一のリクエストで、大きなファイルはマルチパートアップロードで処理します。

**スマートなネットワークスロットリング：**
ネットワーク状況に応じて転送速度を調整し、他のアプリケーションに影響を与えないようにします。

**自動的なコンテンツタイプ検出：**
ファイル拡張子に基づいて適切なContent-Typeを設定します。

```bash
# Content-Typeが自動的に設定される
aws s3 cp index.html s3://mybucket/public/

# 必要に応じて明示的に指定も可能
aws s3 cp style.css s3://mybucket/public/ \
  --content-type "text/css"
```

APIコマンドでContent-Typeを設定するには、常に明示的に指定する必要があります：

```bash
aws s3api put-object --bucket mybucket --key public/style.css \
  --body style.css --content-type "text/css"
```

### パフォーマンスチューニングオプション

高レベルコマンドでは、AWSの設定ファイルを通じて様々なパフォーマンスチューニングが可能です。AWS公式ドキュメント（https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-files.html を参照）に記載されています。

```
# ~/.aws/config
[profile default]
s3 =
  max_concurrent_requests = 20      # 同時リクエスト数
  max_queue_size = 10000            # キューサイズ
  multipart_threshold = 64MB        # マルチパート閾値
  multipart_chunksize = 16MB        # チャンクサイズ
  max_bandwidth = 50MB/s            # 最大帯域幅
  use_accelerate_endpoint = true    # S3 Transfer Accelerationの有効化
  addressing_style = virtual        # アドレッシングスタイル
```

これらの設定により、特定の環境やユースケースに合わせて高レベルコマンドのパフォーマンスを最適化できます。APIコマンドには同様の組み込み最適化機能がないため、全て手動で実装する必要があります。

### 実際のユースケースでの比較

#### 大容量ログファイルのアップロード
**シナリオ:** 15GBのログアーカイブをS3にアップロード

**高レベルコマンド:**
```bash
# たった1行で完了
aws s3 cp logs-archive.tar.gz s3://mybucket/logs/
```

**APIコマンド:**
```bash
# 手動でマルチパートアップロード処理が必要
# 1. ファイルを分割
split -b 100m logs-archive.tar.gz part-

# 2. マルチパートアップロードを開始
# 3. 各パートをアップロード
# 4. マルチパートアップロードを完了
# (合計で数十行のスクリプトが必要)
```

#### 大量の画像ファイルのアップロード
**シナリオ:** 1万枚の製品画像をS3にアップロード

**高レベルコマンド:**
```bash
# 自動的に並列処理で効率的にアップロード
aws s3 cp ./product-images/ s3://mybucket/images/ --recursive
```

**APIコマンド:**
```bash
# 各ファイルを個別にアップロード、並列処理のためには追加のスクリプトが必要
find ./product-images -type f | xargs -P 10 -I {} \
  bash -c 'aws s3api put-object --bucket mybucket --key "images/$(basename {})" --body "{}"'
```

このように、高レベルコマンドは特に大容量ファイルや大量のファイルを扱う場合に、APIコマンドよりも圧倒的に効率的かつ簡潔に操作できることがわかります。

それでは、続きのセクションを作成していきます。

## 4. 具体的なコマンド比較例

実際のユースケースに基づいて、高レベルコマンドとAPIコマンドの使い方を比較してみましょう。

### ファイルアップロードの比較

**高レベルコマンド (cp):**
```bash
aws s3 cp large_file.zip s3://mybucket/backups/
```

**APIコマンド (put-object):**
```bash
aws s3api put-object --bucket mybucket --key backups/large_file.zip --body large_file.zip
```

大きな違いは、高レベルコマンドの場合、ファイルサイズが大きい場合（8MB超）に自動的にマルチパートアップロードが行われることです。AWS公式ドキュメント（https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-services-s3-commands.html を参照）によると、高レベルコマンドでは以下のパラメータでマルチパートアップロードを細かく制御することもできます：

```bash
aws s3 cp large_file.zip s3://mybucket/backups/ \
  --storage-class STANDARD_IA \
  --metadata '{"x-amz-meta-custom":"my-metadata"}' \
  --expected-size 5368709120
```

一方、APIコマンドでマルチパートアップロードを行う場合は、複数のAPIコールを自分で組み合わせる必要があります：

```bash
# マルチパートアップロードの開始
aws s3api create-multipart-upload --bucket mybucket --key backups/large_file.zip

# 各パートのアップロード（複数回実行）
aws s3api upload-part --bucket mybucket --key backups/large_file.zip --part-number 1 \
  --body part1 --upload-id "upload-id-from-create-multipart-upload"

# マルチパートアップロードの完了
aws s3api complete-multipart-upload --bucket mybucket --key backups/large_file.zip \
  --upload-id "upload-id-from-create-multipart-upload" \
  --multipart-upload file://parts.json
```

### バケット内のオブジェクト一覧取得の比較

**高レベルコマンド (ls):**
```bash
# 基本的な一覧表示
aws s3 ls s3://mybucket/

# 再帰的な一覧表示
aws s3 ls s3://mybucket/ --recursive

# 人間が読みやすい形式でサイズを表示
aws s3 ls s3://mybucket/ --human-readable
```

**APIコマンド (list-objects-v2):**
```bash
# 基本的な一覧表示
aws s3api list-objects-v2 --bucket mybucket

# プレフィックス指定での一覧表示
aws s3api list-objects-v2 --bucket mybucket --prefix "folder/"

# 一度に取得するオブジェクト数を制限（ページネーション）
aws s3api list-objects-v2 --bucket mybucket --max-items 100
```

AWS CLI リファレンス（https://docs.aws.amazon.com/cli/latest/reference/s3api/list-objects-v2.html を参照）によると、APIコマンドでは一覧表示の詳細な制御（ページネーション、デリミタ、エンコーディングタイプなど）が可能です。

## 5. どのような場合に高レベルコマンドを使うべきか

AWS公式ドキュメント（https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-services-s3-commands.html を参照）の知見と実務経験に基づき、以下のようなケースでは高レベルコマンドが適しています：

### ユースケースと適用例

1. **大容量ファイルの転送**
   大きなファイル（5GB以上）をアップロードする場合、高レベルコマンドは自動的にマルチパートアップロードを行います。
   
   ```bash
   aws s3 cp large_database_backup.tar.gz s3://mybucket/backups/
   ```

2. **大量のファイル転送**
   多数のファイルを一括で転送する場合、高レベルコマンドは並列処理と再試行ロジックを自動的に実装します。
   
   ```bash
   aws s3 cp /path/to/local/directory/ s3://mybucket/target/ --recursive
   ```

3. **ディレクトリ構造の同期**
   ローカルとS3間でファイルの同期を行いたい場合、変更されたファイルのみを効率的に転送します。
   
   ```bash
   aws s3 sync /local/source/ s3://mybucket/target/ --delete
   ```

4. **シンプルな日常的なファイル操作**
   Linuxコマンドに慣れたユーザーにとって、直感的に使用できます。
   
   ```bash
   aws s3 ls s3://mybucket/
   aws s3 rm s3://mybucket/old_file.txt
   aws s3 mb s3://new-bucket
   ```

### メリットとデメリット

**メリット:**
- 直感的で使いやすいコマンド体系
- 自動的なマルチパートアップロード/ダウンロード
- 並列処理による高速なファイル転送
- 再試行とチェックポイント機能による信頼性向上
- 5TBまでの大容量ファイル転送に対応

**デメリット:**
- S3の高度な設定や特殊な機能へのアクセスが限られる
- APIパラメータの細かい制御が難しい場合がある
- エラーメッセージが抽象的になることがある

## 6. どのような場合に API コマンドを使うべきか

AWS CLI リファレンス（https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html を参照）の情報に基づき、以下のようなケースではAPIコマンドが適しています：

### ユースケースと適用例

1. **S3の高度な機能にアクセスする場合**
   バケットポリシー、CORS設定、ライフサイクルルールなど、高度な設定を行う際に必要です。
   
   ```bash
   aws s3api put-bucket-policy --bucket mybucket --policy file://policy.json
   aws s3api put-bucket-cors --bucket mybucket --cors-configuration file://cors.json
   ```

2. **APIパラメータを細かく制御したい場合**
   タグ付け、メタデータ、ストレージクラスなどの詳細を指定する場合に便利です。
   
   ```bash
   aws s3api put-object --bucket mybucket --key myfile.txt \
     --body myfile.txt --tagging "key1=value1&key2=value2" \
     --metadata '{"custom1":"value1","custom2":"value2"}' \
     --storage-class INTELLIGENT_TIERING
   ```

3. **スクリプト内での使用**
   出力がJSON形式で返されるため、プログラム的に処理しやすいです。
   
   ```bash
   # JSON出力を取得して処理
   objects=$(aws s3api list-objects-v2 --bucket mybucket --prefix "logs/" --output json)
   echo $objects | jq '.Contents[] | .Key'
   ```

4. **バッチ処理やワークフロー自動化**
   特定の条件に合致するオブジェクトだけを処理するなど、細かい条件指定が必要な場合。
   
   ```bash
   # 特定のプレフィックスとタグを持つオブジェクトを検索
   aws s3api list-objects-v2 --bucket mybucket --prefix "archive/" \
     | jq '.Contents[] | .Key' | xargs -I {} \
     aws s3api get-object-tagging --bucket mybucket --key {}
   ```

### メリットとデメリット

**メリット:**
- S3の全API機能にアクセス可能
- 細かなパラメータ制御が可能
- JSON形式の出力で自動処理に適している
- S3の高度な設定や管理機能を使用できる

**デメリット:**
- コマンド構文が複雑
- 大容量ファイル転送には追加の手順が必要
- マルチパートアップロードを手動で管理しなければならない
- 単一のAPIコールに制限されるため、複雑な操作には複数コマンドの組み合わせが必要

## 7. 実践的なシナリオと推奨コマンド

実際のユースケースに基づいて、どちらのコマンド体系が適しているかを見ていきましょう。

### 大容量ファイル転送

**シナリオ:** 8GBのデータベースバックアップファイルをS3にアップロードする

**推奨:** 高レベルコマンド

```bash
# 高レベルコマンドでは自動的にマルチパートアップロードが行われる
aws s3 cp database_backup.sql.gz s3://mybucket/backups/ \
  --storage-class STANDARD_IA \
  --metadata '{"database":"production","date":"2023-05-04"}'
```

AWS公式ドキュメント（https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-services-s3-commands.html を参照）によると、高レベルコマンドの場合、大きなファイルは自動的に分割され、マルチパートアップロードとして処理されます。また、転送中に接続が切れても、再開可能です。

### バッチ処理

**シナリオ:** バケット内の特定のプレフィックス配下にある、特定のタグを持つオブジェクトのみを処理する

**推奨:** APIコマンド

```bash
# APIコマンドを使って特定の条件に合致するオブジェクトのみを処理
aws s3api list-objects-v2 --bucket mybucket --prefix "logs/2023/" \
  --output json | jq -r '.Contents[].Key' | while read key; do
    tags=$(aws s3api get-object-tagging --bucket mybucket --key "$key")
    if echo "$tags" | grep -q "environment=production"; then
      aws s3api copy-object --copy-source mybucket/"$key" \
        --bucket archive-bucket --key "archived/$key"
    fi
done
```

AWS CLI リファレンス（https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html を参照）に記載されているように、APIコマンドはJSON出力と組み合わせることで柔軟なスクリプト処理が可能です。

### ディレクトリ同期

**シナリオ:** ローカルの開発ディレクトリをS3バケットのステージング環境と同期する

**推奨:** 高レベルコマンド

```bash
# 変更されたファイルのみを効率的に転送
aws s3 sync ./src/ s3://mybucket/staging/ \
  --exclude "*.tmp" --exclude "node_modules/*" \
  --delete
```

AWS公式ドキュメント（https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-services-s3-commands.html を参照）によると、syncコマンドは変更されたファイルのみを転送し、`--delete`オプションを使用すると、送信先に存在するが送信元に存在しないファイルも削除します。

## 8. よくある間違いと注意点

S3コマンドを使用する際に気をつけるべき点をいくつか紹介します。

### 容量制限に関する誤解

APIコマンドの`put-object`は5GBが上限です。これを超えるファイルをアップロードしようとすると以下のようなエラーが発生します。

```
An error occurred (EntityTooLarge) when calling the PutObject operation: Your proposed upload exceeds the maximum allowed size
```

大きなファイルをアップロードする場合は、高レベルコマンドを使用するか、APIコマンドでもマルチパートアップロードの手順を踏む必要があります。

### パフォーマンスチューニング

高レベルコマンドでは、以下のような設定でパフォーマンスを調整できます。AWS公式ドキュメント（https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-services-s3-commands.html を参照）に記載されています。

```bash
# ~/.aws/config に以下を追加
[profile default]
s3 =
  max_concurrent_requests = 20
  max_queue_size = 10000
  multipart_threshold = 64MB
  multipart_chunksize = 16MB
```

### 再帰的削除の危険性

`aws s3 rm --recursive`コマンドは強力ですが、誤って使用すると復旧不可能なデータ損失を招く可能性があります。常に`--dryrun`オプションで事前にシミュレーションすることをお勧めします。

```bash
# まずdry-runで確認
aws s3 rm s3://mybucket/important-folder/ --recursive --dryrun

# 問題なければ実行
aws s3 rm s3://mybucket/important-folder/ --recursive
```

### バージョニングが有効なバケットでの注意点

バージョニングが有効なバケットでは、オブジェクトを削除してもバージョンマーカーが残ります。完全に削除するには追加の手順が必要です。AWS CLI リファレンス（https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html を参照）によると、APIコマンドでは`--version-id`パラメータを使用できます。

```bash
# 特定のバージョンを削除
aws s3api delete-object --bucket mybucket --key myfile.txt --version-id "versionId"
```

## 9. 終わりに

AWS CLIを使ったS3操作では、高レベルコマンド（aws s3）とAPIコマンド（aws s3api）の両方を状況に応じて使い分けることが重要です。

高レベルコマンドは：
- 日常的なファイル操作
- 大容量ファイル転送
- 複数ファイルの一括処理
- ディレクトリ同期

に適しています。

一方、APIコマンドは：
- S3の高度な機能へのアクセス
- 細かいパラメータ制御
- スクリプト処理との連携
- 特定の条件に基づいた処理

に適しています。

両方のコマンド体系の特徴を理解し、用途に応じて適切に選択することで、より効率的なS3操作が可能になります。「cpコマンドだけではダメなの？」という疑問に対する答えは、「ケースバイケース」です。単純なファイル転送なら高レベルコマンドで十分ですが、より細かい制御や高度な機能が必要な場合はAPIコマンドが必要になります。

### 次のステップ

- AWS CLIの設定ファイル（`~/.aws/config`）でS3転送のパフォーマンスチューニングを試してみる
- AWS CLIのページネーション機能を使って大量のオブジェクトを扱う方法を学ぶ
- S3のバッチ操作（S3 Batch Operations）についても調査する

## 参考文献・参考サイト

- AWS CLI コマンドリファレンス：S3コマンド（https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-services-s3-commands.html ）
- AWS CLI コマンドリファレンス：API S3コマンド（https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html ）
- AWS CLI コマンドリファレンス：高レベルS3コマンド（https://docs.aws.amazon.com/cli/latest/reference/s3/index.html ）
- Amazon S3 デベロッパーガイド：マルチパートアップロード（https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html ）