2019-11-17

CUI Dropboxクライアント dbxcli を使ってファイルをアップロードしてみた

特定のファイル、ディレクトリの中身だけをDropboxで同期したいと思ったことはありますか?

私の場合はLinuxサーバのバックアップを保存しておくためのストレージとしてDropboxを使いたかったんですが、 Linux用のDropboxデーモンでは除外設定はあるものの、特定のディレクトリだけを同期する方法はないし、 対象以外全部除外するのはあまり現実的な方法ではないでしょう。

あと dropboxd をずっと起動しておくのも気持ち悪い。

そこで 非同期でDropboxを操作するクライアントを探していたら Dropbox謹製のGolang製クライアントがありました。 (ただ、内部で使ってるdropbox-sdk は unofficialっぽい)

GitHub - dropbox/dbxcli: A command line client for Dropbox built using the Go SDKA command line client for Dropbox built using the Go SDK - GitHub - dropbox/dbxcli: A command line client for Dropbox built using the Go SDKhttps://github.com/dropbox/dbxcli

環境にあったバイナリを Releases からダウンロードして配置して実行権限を設定するだけです(ファイル名を変えてもOK)

$ wget https://github.com/dropbox/dbxcli/releases/download/v3.0.0/dbxcli-linux-amd64 $ chmod +x dbxcli-linux-amd64
$ ./dbxcli-linux-amd64 Use dbxcli to quickly interact with your Dropbox, upload/download files, manage your team and more. It is easy, scriptable and works on all platforms! Usage: dbxcli [command] Available Commands: account Display account information cp Copy a file or folder to a different location in the user's Dropbox. If the source path is a folder all its contents will be copied. du Display usage information get Download a file help Help about any command logout Log out of the current session ls List files and folders mkdir Create a new directory mv Move files put Upload files restore Restore files revs List file revisions rm Remove files search Search share Sharing commands team Team management commands version Print version information Flags: --as-member string Member ID to perform action as -h, --help help for dbxcli -v, --verbose Enable verbose logging Use "dbxcli [command] --help" for more information about a command.

コマンドはなんとなくヘルプ見ればわかると思うので全ては解説しませんが、 個人的に重要だと思う accountput について簡単に解説します。

dbxcli と dropbox を紐付け、その情報を閲覧するのが account です。

最初に実行すると 認証用のURLと Enter the authorization code here: というメッセージが表示されるので、

URLにアクセスして取得した認証コードを貼り付ければ紐付け完了です。

$ ./dbxcli-linux-amd64 account 1. Go to https://www.dropbox.com/1/oauth2/authorize?client_id=AAAAAAAAAAAAAAAA&response_type=code&state=state 2. Click "Allow" (you might have to log in first). 3. Copy the authorization code. Enter the authorization code here: BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB Logged in as User name <username@example.com> Account Id: dbid:CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC Account Type: pro Locale: en Referral Link: https://www.dropbox.com/referrals/DDDDDDDDDDDDDDDDDDDDDDDDD-8?src=app9-999999 Profile Photo Url: Paired Account: false

put はファイルをアップロードするためのコマンドです。

$ ./dbxcli-linux-amd64 put --help Upload files Usage: dbxcli put [flags] <source> [<target>] Flags: -h, --help help for put Global Flags: --as-member string Member ID to perform action as -v, --verbose Enable verbose logging

アップロード ファイルのパスが必須で、アップロード のパス(Dropbox側) は省略が可能です。

アップロード先を省略すると Dropboxのルートディレクトリ直下にコピーされるので注意しましょう。

# アップロード先はファイル名まで指定しなければいけない $ ./dbxcli-linux-amd64 put test.txt test Uploading 4 B/4 B Error: path/conflict/folder/ $ ./dbxcli-linux-amd64 put test.txt test/test.txt Uploading 4 B/4 B

test/test.txt がアップロードされてますね。

さて、ディレクトリごとアップロードできるのか? という疑問が湧いてきますが、残念ながらできません。

当該クライアントはDropboxのAPIをラップしているだけなのでディレクトリのアップロードは 利用者が再帰的にディレクトリを走査して実行してくれという方針なんでしょう。

ということでアップロードするシェルスクリプトを簡単に作りました。

#!/bin/bash DST_ROOT="backups" SRC_ROOT="./images/" if [ "$1" != "" ]; then SRC_ROOT="${SRC_ROOT}/$1" fi if [ "$2" != "" ]; then SRC_ROOT="${SRC_ROOT}/$2" fi if [ "$3" != "" ]; then SRC_ROOT="${SRC_ROOT}/$3" fi echo ROOT: $SRC_ROOT find $SRC_ROOT -type f 2>/dev/null | while read FILE do echo ==== $FILE ==== ./dbxcli-linux-amd64 put ${FILE} "${DST_ROOT}/${FILE#*/}" done
warning
  • bash であれば パス内に カレントディレクトリを意味する単体の . や 連続する / があっても処理してくれますが、アップロード先のパスにこのような文字列があると Error: json: cannot unmarshal object into Go value of type string というエラーがかえってくるので、 前もってパスを整形しておきましょう。
  • (JSON化のエラーメッセージなのはよくわからん
NG
  • /path/./to/file
NG
  • /path//to/file
OK
  • /path/to/file (先頭のスラッシュはあってもなくてもどちらでもよい)

私の場合は日次で自動実行することを想定してディレクトリを区切っています。

手動実行では年単位、月単位でも実行したくなる可能性があるので、 年月日を引数で渡せるようにしてあります。

ちなみに実行するとこんな感じになります(ちゃんとアップロードされてました)

$ ./upload.sh $(date "+%Y") ROOT: ./images/2019 ==== ./images/2019/10/20/2/image.png ==== Uploading 5.8 KiB/5.8 KiB ==== ./images/2019/10/20/2/thumb_image.png ==== Uploading 5.4 KiB/5.4 KiB ==== ./images/2019/10/20/2/thumb100_image.png ==== Uploading 2.2 KiB/2.2 KiB
info
  • cp コマンドはDropbox上のファイルをコピーする操作です。
  • Dropbox上のファイル(ディレクトリ)をコピーして Dropbox上に配置するだけなのでアップロードには使えません。

当然自動同期に比べるとちまちまとめんどくさいですが、 バックアップ用途では小回りがきくこちらのほうが向いている気がします。