0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Windows端末のaws-cliでバケットをローカルにダウンロードしようとしたけど、S3オブジェクトキーにコロンがあってエラーになった話

Posted at

S3バケットのファイルをaws s3 cp s3://<<バケット名>> <<ダウンロードディレクトリ>> --recursiveと再帰的にダウンロードしようとした際に、オブジェクトキーにコロン(:)が含まれていてうまくダウンロードできなかった話。

これは後述するWindowsで利用できない文字 かつ S3のオブジェクトキーで利用が推奨されていない文字である コロン(:)が悪さをしていたケースとなります。

本記事ではコロン等がありWIndowsでは一括でローカルにダウンロードできなかった際の対策をPowerShellで書いてみました。

Windowsではファイルに利用できない文字がある

Windowsではファイルに利用できない文字が色々とありますが、コロン(:)はその中の一文字です。

ちなみにWindowsで利用できない名前は下記PathクラスのGetInvalidFileNameCharsメソッドで取得できます。

Path.GetInvalidFileNameChars Method

image.png

S3ではオブジェクトキーの命名についてと非推奨の文字がある

オブジェクトキー名の作成

S3ではバケット内のオブジェクトを一意に識別する要素としてオブジェクトキーがありますが。

このオブジェクトキーについて、AWSドキュメントでは上記のようにガイドラインと非推奨な文字が記載されています。

Windowsでは利用できないコロン(:)について、非推奨とはなっていますが。
あくまで非推奨のためオブジェクトキーとしては利用できます。

Windowsでは利用できない文字が、S3のオブジェクトキーにあるとどうなるか

上記のような差異があるため、S3のオブジェクトキーにWindowsの駄目文字を含んでいる場合に、Windows上でaws cliにて該当ファイルを含むS3バケットを'sync'だったり、cp--recursiveオプションをつけて一括ダウンロードしようとした場合。

オブジェクトキーに含まれる駄目文字がネックになってダウンロードが失敗します。

ファイル名にWindowsの駄目文字が含まれているだけなので、ダウンロード先の指定でコロンを抜いたファイル名にすれば問題なくダウンロードできます。


# 下記はコマンドではfoo:bar.txtというファイルを作成しようとしてエラー
# $lastexitcodeが1で終了します
aws cp s3://<<バケット名>>/foo:bar.txt ./

#下記はダウンロード先をfoo_bar.txtという文字に変えているのでダウンロードOK
aws cp s3://<<バケット名>>/foo:bar.txt .foo_bar.txt

ダウンロード対象のファイル名が少ない場合は、1ファイルずつリネームしながらダウンロードすれば問題ありませんが、対象が多い場合面倒です。

今回駄目だったケースについて

回避策の前に、今回駄目だったケースについて。

基本はコロンのような非推奨な制約のある文字をS3のオブジェクトキーに使わないようにするのが一番の解決策かとは思います。

が、そもそも今回問題となったケースについて。

今回、一括でダウンロードしたかったバケットはAWS Backupの標準機能 Backup Audit ManagerAWS Bakupのバックアップ結果をS3にレポート出力しているバケットでした。

Backup Audit ManagerではS3に保管するオブジェクトキーに日付情報が含まれていますが、日付情報がISO 8601となっており、このため出力されるオブジェクトキーにコロンが含まれてしまいます。

AWS BackupAudit Managerとバックアップの監査およびレポートの作成をする

image.png

上記画像をみると、出力されたレポートのオブジェクトキーにコロンが含まれている事がわかります。

このため、このままの状態でダウンロード先を変更しないでaws-cliコマンドでダウンロードするとエラーになります。

なお、マネジメントコンソール上からこのファイルをダウンロードした場合は、コロン_に置換されてダウンロードされる動作となっていました。

PowerShellでダウンロード先の駄目文字を置換しながら一括ダウンロードする

ファイルの数がそこそこあったのでPowerShellで下記のように記述して一括してダウンロードしてみました。

$bucketName = '<<バケット名>>'
$directory = 'c:\temp\backup_report'

# s3バケットのオブジェクトキー一覧をリスト
$s3ObjectKeys = aws s3api list-objects --bucket $bucketName --output text --query "Contents[].{Key:Key}"

foreach ( $s3ObjectKey in $s3ObjectKeys ) {

    $source = "s3://{0}/{1}" -f $bucketName , $s3ObjectKey

    # 駄目文字をリプレイス(ディレクトリ構造は残したいので/はリプレイス対象から除外)
    $replaceS3ObjectKey = [RegEx]::Replace($source, "[{0}]" -f [RegEx]::Escape(([string][System.IO.Path]::GetInvalidFileNameChars() -replace '/' , '')) , '')
    $destinationPath = Join-Path -Path $directory  -ChildPath $replaceS3ObjectKey

    # s3 cpでダウンロード
    aws s3 cp $source $destinationPath

}

総評

バケットを一括ダウンロードしようとしてファイルが保存されず、最初は訳がわかりませんでしたが。

--debugをオプションをつけて実行し、結果を眺めていると、これはコロンが不味そうだとわかりました。

検索すると下記のissueがありました。

Can't sync to Windows when colon in file name (cont..) #5813

AWS標準機能を用いて出力したレポートのオブジェクトキーに非推奨のコロンが入っているのはちょっと残念な気はしますが。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?