tl;dr
代わりに mc コマンドを使うこと。
問題
gsutil
を使い、macOS 上で日本語文字バイトを含むファイル名をつけたファイルを転送しようとするとエラーになる。
CommandException: Couldn't write tracker file (/Users/you/.gsutil/tracker-files/upload_TRACKER_a5a3118b61060366b4e074bbd40c0051f7ca5c29.��.m4a__JSON.url): Illegal byte sequence. This can happen if gsutil is configured to save tracker files to an unwritable directory)
ローカルディスク上に、日本語を含むファイル名で一時ファイルを正しく保存できないようだ。Python 自体のエンコーディングの扱いの問題だと思われる。
未検証だが HFS+
時代は問題なかったはずなので、起動ディスクが Apple File System (APFS)
でフォーマットされているとダメである可能性がある。(メモ:HFS+ 時代からダメな場合もある模様)
うまくいかないパターン集
いろいろ試行錯誤をしたログ。
環境変数を指定する
- LC_ALL 系
- LANG
- PYTHONIOENCODING
どれも効果がなかった。
Python スクリプトにエンコードの設定を入れてみる
直接スクリプトを編集しデフォルトエンコーディングを指定する。だいぶ昔に試したため詳細は失念。
awscli を使う
たとえば gcs
という profile を作成して試しても:
aws --profile=gcs --endpoint-url https://storage.googleapis.com/ s3 ls
バケット一覧は参照できるが、オブジェクトは見えない。
aws --profile=gcs --endpoint-url https://storage.googleapis.com/ s3 ls s3://your-bucket/
An error occurred (InvalidArgument) when calling the ListObjects operation: Invalid argument.
--debug
をつけて実行すると、次のようにパラメータに互換性がないため失敗することがわかる。
Invalid query parameter(s): [encoding-type]
Docker を使う
google/cloud-sdk:latest というイメージがあるので起動して、gcloud などの設定を済ませてみても:
docker run -it --rm google/cloud-sdk:latest bash
> gcloud auth login
> gsutil config
...
> gsutil rsync -r -e -C /from/ gs://your-bucket/to/
ascii
以外にエンコードする手段が分からない。
Caught non-retryable exception while listing file://.: 'ascii' codec can't encode characters in position 15-20: ordinal not in range(128)
Mountain Duck を使う
Mountain Duck は、Cyberduck を使ってネットワークディスクをマウントする拡張アプリ(有償)。Google Cloud Storage を macOS にマウントできる。
マウントされるパスは ~/Library/Group Containers/G69SCX94XU.duck/Library/Application Support/duck/Volumes/gcs
などとなり Finder から参照できる。
ただ、cp
コマンドは使えるのだが rsync
コマンドで同期を取ることはできない。
rsync: close failed on "/Users/you/Library/Group Containers/G69SFX91XU.duck/Library/Application Support/duck/Volumes/gcs/your-bucket/test.txt.0Bf5R6": Unknown error: 10006 (10006)
rsync error: error in file IO (code 11) at receiver.c(853) [receiver=3.1.3]
代替手段
minio に含まれる mc コマンドを使う。gsutil とはコマンド名や挙動に互換性はないので注意。
brew install minio-mc
設定例については README に記述がある。
mc config host add gcs https://storage.googleapis.com xxxx xxxxxxxxxxxxxxxx
mc mirror --force /from/ gcs/your-bucket/to/
上書きしたい場合は --force
が必要。削除をするなら --remove
を指定する。
一部の日本語文字は化けて表示されるが、出力自体は見やすい。欠点として、特定のファイルを除外するオプションがない。
まとめ
awscli
や gsutil
がいつか対応するまでは、mc
コマンドでひとまず代用できる。