看到有人用dropbox备份网站数据,所以今天也试了一下,记得以前是一个python脚本,这是用的是bash 脚本,利用dropbox的api来上传下载的,很方便,脚本的地址是Dropbox-Uploader/dropbox_uploader.sh at master · andreafabrizi/Dropbox-Uploader · GitHub ,感谢作者分享这个脚本。
可以到git下载dropbox_uploader.sh,地址为:https://github.com/andreafabrizi/Dropbox-Uploader
或者也可以直接拷贝代码,保存为dropbox_uploader.sh,注意拷贝的时候最好是复制到文本编辑器里面,如notepad++之类的
#!/usr/bin/env bash## Dropbox Uploader## Copyright (C) 2010-2014 Andrea Fabrizi <andrea.fabrizi@gmail.com>## This program is free software; you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation; either version 2 of the License, or# (at your option) any later version.## This program is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU General Public License for more details.## You should have received a copy of the GNU General Public License# along with this program; if not, write to the Free Software# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.##Default configuration fileCONFIG_FILE=~/.dropbox_uploader#Default chunk size in Mb for the upload process#It is recommended to increase this value only if you have enough free space on your /tmp partition#Lower values may increase the number of http requestsCHUNK_SIZE=4#Curl location#If not set, curl will be searched into the $PATH#CURL_BIN="/usr/bin/curl"#Default valuesTMP_DIR="/tmp"DEBUG=0QUIET=0SHOW_PROGRESSBAR=0SKIP_EXISTING_FILES=0ERROR_STATUS=0#Don"t edit these...API_REQUEST_TOKEN_URL="https://api.dropbox.com/1/oauth/request_token"API_USER_AUTH_URL="https://www2.dropbox.com/1/oauth/authorize"API_ACCESS_TOKEN_URL="https://api.dropbox.com/1/oauth/access_token"API_CHUNKED_UPLOAD_URL="https://api-content.dropbox.com/1/chunked_upload"API_CHUNKED_UPLOAD_COMMIT_URL="https://api-content.dropbox.com/1/commit_chunked_upload"API_UPLOAD_URL="https://api-content.dropbox.com/1/files_put"API_DOWNLOAD_URL="https://api-content.dropbox.com/1/files"API_DELETE_URL="https://api.dropbox.com/1/fileops/delete"API_MOVE_URL="https://api.dropbox.com/1/fileops/move"API_COPY_URL="https://api.dropbox.com/1/fileops/copy"API_METADATA_URL="https://api.dropbox.com/1/metadata"API_INFO_URL="https://api.dropbox.com/1/account/info"API_MKDIR_URL="https://api.dropbox.com/1/fileops/create_folder"API_SHARES_URL="https://api.dropbox.com/1/shares"APP_CREATE_URL="https://www2.dropbox.com/developers/apps"RESPONSE_FILE="$TMP_DIR/du_resp_$RANDOM"CHUNK_FILE="$TMP_DIR/du_chunk_$RANDOM"TEMP_FILE="$TMP_DIR/du_tmp_$RANDOM"BIN_DEPS="sed basename date grep stat dd mkdir"VERSION="0.14"umask 077#Check the shellif [ -z "$BASH_VERSION" ]; thenecho -e "Error: this script requires the BASH shell!"exit 1fishopt -s nullglob #Bash allows filename patterns which match no files to expand to a null string, rather than themselvesshopt -s dotglob #Bash includes filenames beginning with a "." in the results of filename expansion#Look for optional config file parameterwhile getopts ":qpskdf:" opt; docase $opt inf) CONFIG_FILE=$OPTARG;;d) DEBUG=1;;q) QUIET=1;;p) SHOW_PROGRESSBAR=1;;k) CURL_ACCEPT_CERTIFICATES="-k";;s) SKIP_EXISTING_FILES=1;;?) echo "Invalid option: -$OPTARG" >&2 exit 1;;:) echo "Option -$OPTARG requires an argument." >&2 exit 1;; esacdoneif [[ $DEBUG != 0 ]]; thenecho $VERSIONset -xRESPONSE_FILE="$TMP_DIR/du_resp_debug"fiif [[ $CURL_BIN == "" ]]; thenBIN_DEPS="$BIN_DEPS curl"CURL_BIN="curl"fi#Dependencies checkwhich $BIN_DEPS > /dev/nullif [[ $? != 0 ]]; thenfor i in $BIN_DEPS; dowhich $i > /dev/null ||NOT_FOUND="$i $NOT_FOUND"doneecho -e "Error: Required program could not be found: $NOT_FOUND"exit 1fi#Check if readlink is installed and supports the -m option#It"s not necessary, so no problem if it"s not installedwhich readlink > /dev/nullif [[ $? == 0 && $(readlink -m "//test" 2> /dev/null) == "/test" ]]; thenHAVE_READLINK=1elseHAVE_READLINK=0fi#Forcing to use the builtin printf, if it"s present, because it"s better#otherwise the external printf program will be used#Note that the external printf command can cause character encoding issues!builtin printf "" 2> /dev/nullif [[ $? == 0 ]]; thenPRINTF="builtin printf"PRINTF_OPT="-v o"elsePRINTF=$(which printf)if [[ $? != 0 ]]; thenecho -e "Error: Required program could not be found: printf"fiPRINTF_OPT=""fi#Print the message based on $QUIET variablefunction print{if [[ $QUIET == 0 ]]; thenecho -ne "$1";fi}#Returns unix timestampfunction utime{echo $(date +%s)}#Remove temporary filesfunction remove_temp_files{if [[ $DEBUG == 0 ]]; thenrm -fr "$RESPONSE_FILE"rm -fr "$CHUNK_FILE"rm -fr "$TEMP_FILE"fi}#Returns the file size in bytes# generic GNU Linux: linux-gnu# windows cygwin:cygwin# raspberry pi: linux-gnueabihf# macosx:darwin10.0# freebsd:FreeBSD# qnap: linux-gnueabi# iOS:darwin9function file_size{#Some embedded linux devicesif [[ $OSTYPE == "linux-gnueabi" || $OSTYPE == "linux-gnu" ]]; thenstat -c "%s" "$1"return#Generic Unixelif [[ ${OSTYPE:0:5} == "linux" || $OSTYPE == "cygwin" || ${OSTYPE:0:7} == "solaris" ]]; thenstat --format="%s" "$1"return#BSD, OSX and other OSselsestat -f "%z" "$1"returnfi}#Usagefunction usage{echo -e "Dropbox Uploader v$VERSION"echo -e "Andrea Fabrizi - andrea.fabrizi@gmail.com
"echo -e "Usage: $0 COMMAND [PARAMETERS]..."echo -e "
Commands:"echo -e " upload<LOCAL_FILE/DIR ...> <REMOTE_FILE/DIR>"echo -e " download <REMOTE_FILE/DIR> [LOCAL_FILE/DIR]"echo -e " delete<REMOTE_FILE/DIR>"echo -e " move <REMOTE_FILE/DIR> <REMOTE_FILE/DIR>"echo -e " copy <REMOTE_FILE/DIR> <REMOTE_FILE/DIR>"echo -e " mkdir<REMOTE_DIR>"echo -e " list [REMOTE_DIR]"echo -e " share<REMOTE_FILE>"echo -e " info"echo -e " unlink"echo -e "
Optional parameters:"echo -e " -f <FILENAME> Load the configuration file from a specific file"echo -e " -sSkip already existing files when download/upload. Default: Overwrite"echo -e " -dEnable DEBUG mode"echo -e " -qQuiet mode. Don"t show messages"echo -e " -pShow cURL progress meter"echo -e " -kDoesn"t check for SSL certificates (insecure)"echo -en "
For more info and examples, please see the README file.
"remove_temp_filesexit 1}#Check the curl exit codefunction check_http_response{CODE=$?#Checking curl exit codecase $CODE in#OK0);;#Proxy error5)print "
Error: Couldn"t resolve proxy. The given proxy host could not be resolved.
"remove_temp_filesexit 1;;#Missing CA certificates60|58)print "
Error: cURL is not able to performs peer SSL certificate verification.
"print "Please, install the default ca-certificates bundle.
"print "To do this in a Debian/Ubuntu based system, try:
"print " sudo apt-get install ca-certificates
"print "If the problem persists, try to use the -k option (insecure).
"remove_temp_filesexit 1;;6)print "
Error: Couldn"t resolve host.
"remove_temp_filesexit 1;;7)print "
Error: Couldn"t connect to host.
"remove_temp_filesexit 1;;esac#Checking response file for generic errorsif grep -q "HTTP/1.1 400" "$RESPONSE_FILE"; thenERROR_MSG=$(sed -n -e "s/{"error": "([^"]*)"}/1/p" "$RESPONSE_FILE")case $ERROR_MSG in *access?attempt?failed?because?this?app?is?not?configured?to?have*)echo -e "
Error: The Permission type/Access level configured doesn"t match the DropBox App settings!
Please run "$0 unlink" and try again."exit 1;;esacfi}#Urlencodefunction urlencode{local string="${1}"local strlen=${#string}local encoded=""for (( pos=0 ; pos<strlen ; pos++ )); doc=${string:$pos:1}case "$c" in[-_.~a-zA-Z0-9] ) o="${c}" ;;* ) $PRINTF $PRINTF_OPT "%%%02x" ""$c"esacencoded+="${o}"doneecho "$encoded"}function normalize_path{path=$(echo -e "$1")if [[ $HAVE_READLINK == 1 ]]; thenreadlink -m "$path"elseecho "$path"fi}#Check if it"s a file or directory#Returns FILE/DIR/ERRfunction db_stat{local FILE=$(normalize_path "$1")#Checking if it"s a file or a directory$CURL_BIN $CURL_ACCEPT_CERTIFICATES -s --show-error --globoff -i -o "$RESPONSE_FILE" "$API_METADATA_URL/$ACCESS_LEVEL/$(urlencode "$FILE")?oauth_consumer_key=$APPKEY&oauth_token=$OAUTH_ACCESS_TOKEN&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26$OAUTH_ACCESS_TOKEN_SECRET&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM" 2> /dev/nullcheck_http_response#Even if the file/dir has been deleted from DropBox we receive a 200 OK response#So we must check if the file exists or if it has been deletedif grep -q ""is_deleted":" "$RESPONSE_FILE"; thenlocal IS_DELETED=$(sed -n "s/.*"is_deleted":.([^,]*).*/1/p" "$RESPONSE_FILE")elselocal IS_DELETED="false"fi#Exits...grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"if [[ $? == 0 && $IS_DELETED != "true" ]]; thenlocal IS_DIR=$(sed -n "s/^(.*)"contents":.[.*/1/p" "$RESPONSE_FILE")#It"s a directoryif [[ $IS_DIR != "" ]]; thenecho "DIR"#It"s a fileelseecho "FILE"fi#Doesn"t existselseecho "ERR"fi}#Generic upload wrapper around db_upload_file and db_upload_dir functions#$1 = Local source file/dir#$2 = Remote destination file/dirfunction db_upload{local SRC=$(normalize_path "$1")local DST=$(normalize_path "$2")#Checking if the file/dir existsif [[ ! -e $SRC && ! -d $SRC ]]; thenprint " > No such file or directory: $SRC
"ERROR_STATUS=1returnfi#Checking if the file/dir has read permissionsif [[ ! -r $SRC ]]; thenprint " > Error reading file $SRC: permission denied
"ERROR_STATUS=1returnfi#Checking if DST it"s a folder or if it doesn" exists (in this case will be the destination name)TYPE=$(db_stat "$DST")if [[ $TYPE == "DIR" ]]; thenlocal filename=$(basename "$SRC")DST="$DST/$filename"fi#It"s a directoryif [[ -d $SRC ]]; thendb_upload_dir "$SRC" "$DST"#It"s a fileelif [[ -e $SRC ]]; thendb_upload_file "$SRC" "$DST"#Unsupported object...elseprint " > Skipping not regular file "$SRC"
"fi}#Generic upload wrapper around db_chunked_upload_file and db_simple_upload_file#The final upload function will be choosen based on the file size#$1 = Local source file#$2 = Remote destination filefunction db_upload_file{local FILE_SRC=$(normalize_path "$1")local FILE_DST=$(normalize_path "$2")shopt -s nocasematch#Checking not allowed file namesbasefile_dst=$(basename "$FILE_DST")if [[ $basefile_dst == "thumbs.db" || $basefile_dst == "desktop.ini" || $basefile_dst == ".ds_store" || $basefile_dst == "icon
" || $basefile_dst == ".dropbox" || $basefile_dst == ".dropbox.attr" ]]; thenprint " > Skipping not allowed file name "$FILE_DST"
"returnfishopt -u nocasematch#Checking file sizeFILE_SIZE=$(file_size "$FILE_SRC")#Checking if the file already existsTYPE=$(db_stat "$FILE_DST")if [[ $TYPE != "ERR" && $SKIP_EXISTING_FILES == 1 ]]; thenprint " > Skipping already existing file "$FILE_DST"
"returnfiif [[ $FILE_SIZE -gt 157286000 ]]; then#If the file is greater than 150Mb, the chunked_upload API will be useddb_chunked_upload_file "$FILE_SRC" "$FILE_DST"elsedb_simple_upload_file "$FILE_SRC" "$FILE_DST"fi}#Simple file upload#$1 = Local source file#$2 = Remote destination filefunction db_simple_upload_file{local FILE_SRC=$(normalize_path "$1")local FILE_DST=$(normalize_path "$2")if [[ $SHOW_PROGRESSBAR == 1 && $QUIET == 0 ]]; thenCURL_PARAMETERS="--progress-bar"LINE_CR="
"elseCURL_PARAMETERS="-s"LINE_CR=""fiprint " > Uploading "$FILE_SRC" to "$FILE_DST"... $LINE_CR"$CURL_BIN $CURL_ACCEPT_CERTIFICATES $CURL_PARAMETERS -i --globoff -o "$RESPONSE_FILE" --upload-file "$FILE_SRC" "$API_UPLOAD_URL/$ACCESS_LEVEL/$(urlencode "$FILE_DST")?oauth_consumer_key=$APPKEY&oauth_token=$OAUTH_ACCESS_TOKEN&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26$OAUTH_ACCESS_TOKEN_SECRET&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM"check_http_response#Checkif grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; thenprint "DONE
"elseprint "FAILED
"print "An error occurred requesting /upload
"ERROR_STATUS=1fi}#Chunked file upload#$1 = Local source file#$2 = Remote destination filefunction db_chunked_upload_file{local FILE_SRC=$(normalize_path "$1")local FILE_DST=$(normalize_path "$2")print " > Uploading "$FILE_SRC" to "$FILE_DST""local FILE_SIZE=$(file_size "$FILE_SRC")local OFFSET=0local UPLOAD_ID=""local UPLOAD_ERROR=0local CHUNK_PARAMS=""#Uploading chunks...while ([[ $OFFSET != $FILE_SIZE ]]); dolet OFFSET_MB=$OFFSET/1024/1024#Create the chunkdd if="$FILE_SRC" of="$CHUNK_FILE" bs=1048576 skip=$OFFSET_MB count=$CHUNK_SIZE 2> /dev/null#Only for the first request these parameters are not includedif [[ $OFFSET != 0 ]]; thenCHUNK_PARAMS="upload_id=$UPLOAD_ID&offset=$OFFSET"fi#Uploading the chunk...$CURL_BIN $CURL_ACCEPT_CERTIFICATES -s --show-error --globoff -i -o "$RESPONSE_FILE" --upload-file "$CHUNK_FILE" "$API_CHUNKED_UPLOAD_URL?$CHUNK_PARAMS&oauth_consumer_key=$APPKEY&oauth_token=$OAUTH_ACCESS_TOKEN&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26$OAUTH_ACCESS_TOKEN_SECRET&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM" 2> /dev/nullcheck_http_response#Checkif grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; thenprint "."UPLOAD_ERROR=0UPLOAD_ID=$(sed -n "s/.*"upload_id": *"*([^"]*)"*.*/1/p" "$RESPONSE_FILE")OFFSET=$(sed -n "s/.*"offset": *([^}]*).*/1/p" "$RESPONSE_FILE")elseprint "*"let UPLOAD_ERROR=$UPLOAD_ERROR+1#On error, the upload is retried for max 3 timesif [[ $UPLOAD_ERROR -gt 2 ]]; thenprint " FAILED
"print "An error occurred requesting /chunked_upload
"ERROR_STATUS=1returnfifidoneUPLOAD_ERROR=0#Commit the uploadwhile (true); do$CURL_BIN $CURL_ACCEPT_CERTIFICATES -s --show-error --globoff -i -o "$RESPONSE_FILE" --data "upload_id=$UPLOAD_ID&oauth_consumer_key=$APPKEY&oauth_token=$OAUTH_ACCESS_TOKEN&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26$OAUTH_ACCESS_TOKEN_SECRET&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM" "$API_CHUNKED_UPLOAD_COMMIT_URL/$ACCESS_LEVEL/$(urlencode "$FILE_DST")" 2> /dev/nullcheck_http_response#Checkif grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; thenprint "."UPLOAD_ERROR=0breakelseprint "*"let UPLOAD_ERROR=$UPLOAD_ERROR+1#On error, the commit is retried for max 3 timesif [[ $UPLOAD_ERROR -gt 2 ]]; thenprint " FAILED
"print "An error occurred requesting /commit_chunked_upload
"ERROR_STATUS=1returnfifidoneprint " DONE
"}#Directory upload#$1 = Local source dir#$2 = Remote destination dirfunction db_upload_dir{local DIR_SRC=$(normalize_path "$1")local DIR_DST=$(normalize_path "$2")#Creatig remote directorydb_mkdir "$DIR_DST"for file in "$DIR_SRC/"*; dodb_upload "$file" "$DIR_DST"done}#Returns the free space on DropBox in bytesfunction db_free_quota{$CURL_BIN $CURL_ACCEPT_CERTIFICATES -s --show-error --globoff -i -o "$RESPONSE_FILE" --data "oauth_consumer_key=$APPKEY&oauth_token=$OAUTH_ACCESS_TOKEN&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26$OAUTH_ACCESS_TOKEN_SECRET&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM" "$API_INFO_URL" 2> /dev/nullcheck_http_response#Checkif grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; thenquota=$(sed -n "s/.*"quota": ([0-9]*).*/1/p" "$RESPONSE_FILE")used=$(sed -n "s/.*"normal": ([0-9]*).*/1/p" "$RESPONSE_FILE")let free_quota=$quota-$usedecho $free_quotaelseecho 0fi}#Generic download wrapper#$1 = Remote source file/dir#$2 = Local destination file/dirfunction db_download{local SRC=$(normalize_path "$1")local DST=$(normalize_path "$2")TYPE=$(db_stat "$SRC")#It"s a directoryif [[ $TYPE == "DIR" ]]; then#If the DST folder is not specified, I assume that is the current directoryif [[ $DST == "" ]]; thenDST="."fi#Checking if the destination directory existsif [[ ! -d $DST ]]; thenlocal basedir=""elselocal basedir=$(basename "$SRC")filocal DEST_DIR=$(normalize_path "$DST/$basedir")print " > Downloading "$SRC" to "$DEST_DIR"...
"print " > Creating local directory "$DEST_DIR"... "mkdir -p "$DEST_DIR"#Checkif [[ $? == 0 ]]; thenprint "DONE
"elseprint "FAILED
"ERROR_STATUS=1returnfi#Extracting directory content [...]#and replacing "}, {" with "}
{"#I don"t like this piece of code... but seems to be the only way to do this with SED, writing a portable code...local DIR_CONTENT=$(sed -n "s/.*: [{(.*)/1/p" "$RESPONSE_FILE" | sed "s/}, *{/}{/g")#Extracting files and subfoldersTMP_DIR_CONTENT_FILE="${RESPONSE_FILE}_$RANDOM"echo "$DIR_CONTENT" | sed -n "s/.*"path": *"([^"]*)",.*"is_dir": *([^"]*),.*/1:2/p" > $TMP_DIR_CONTENT_FILE#For each entry...while read -r line; dolocal FILE=${line%:*}local TYPE=${line#*:}#Removing unneeded /FILE=${FILE##*/}if [[ $TYPE == "false" ]]; thendb_download_file "$SRC/$FILE" "$DEST_DIR/$FILE"elsedb_download "$SRC/$FILE" "$DEST_DIR"fidone < $TMP_DIR_CONTENT_FILErm -fr $TMP_DIR_CONTENT_FILE#It"s a fileelif [[ $TYPE == "FILE" ]]; then#Checking DSTif [[ $DST == "" ]]; thenDST=$(basename "$SRC")fi#If the destination is a directory, the file will be download intoif [[ -d $DST ]]; thenDST="$DST/$SRC"fidb_download_file "$SRC" "$DST"#Doesn"t existselseprint " > No such file or directory: $SRC
"ERROR_STATUS=1returnfi}#Simple file download#$1 = Remote source file#$2 = Local destination filefunction db_download_file{local FILE_SRC=$(normalize_path "$1")local FILE_DST=$(normalize_path "$2")if [[ $SHOW_PROGRESSBAR == 1 && $QUIET == 0 ]]; thenCURL_PARAMETERS="--progress-bar"LINE_CR="
"elseCURL_PARAMETERS="-s"LINE_CR=""fi#Checking if the file already existsif [[ -e $FILE_DST && $SKIP_EXISTING_FILES == 1 ]]; thenprint " > Skipping already existing file "$FILE_DST"
"returnfi#Creating the empty file, that for two reasons:#1) In this way I can check if the destination file is writable or not#2) Curl doesn"t automatically creates files with 0 bytes sizedd if=/dev/zero of="$FILE_DST" count=0 2> /dev/nullif [[ $? != 0 ]]; thenprint " > Error writing file $FILE_DST: permission denied
"ERROR_STATUS=1returnfiprint " > Downloading "$FILE_SRC" to "$FILE_DST"... $LINE_CR"$CURL_BIN $CURL_ACCEPT_CERTIFICATES $CURL_PARAMETERS --globoff -D "$RESPONSE_FILE" -o "$FILE_DST" "$API_DOWNLOAD_URL/$ACCESS_LEVEL/$(urlencode "$FILE_SRC")?oauth_consumer_key=$APPKEY&oauth_token=$OAUTH_ACCESS_TOKEN&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26$OAUTH_ACCESS_TOKEN_SECRET&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM"check_http_response#Checkif grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; thenprint "DONE
"elseprint "FAILED
"rm -fr "$FILE_DST"ERROR_STATUS=1returnfi}#Prints account infofunction db_account_info{print "Dropbox Uploader v$VERSION
"print " > Getting info... "$CURL_BIN $CURL_ACCEPT_CERTIFICATES -s --show-error --globoff -i -o "$RESPONSE_FILE" --data "oauth_consumer_key=$APPKEY&oauth_token=$OAUTH_ACCESS_TOKEN&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26$OAUTH_ACCESS_TOKEN_SECRET&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM" "$API_INFO_URL" 2> /dev/nullcheck_http_response#Checkif grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; thenname=$(sed -n "s/.*"display_name": "([^"]*).*/1/p" "$RESPONSE_FILE")echo -e "
Name: $name"uid=$(sed -n "s/.*"uid": ([0-9]*).*/1/p" "$RESPONSE_FILE")echo -e "UID: $uid"email=$(sed -n "s/.*"email": "([^"]*).*/1/p" "$RESPONSE_FILE")echo -e "Email: $email"quota=$(sed -n "s/.*"quota": ([0-9]*).*/1/p" "$RESPONSE_FILE")let quota_mb=$quota/1024/1024echo -e "Quota: $quota_mb Mb"used=$(sed -n "s/.*"normal": ([0-9]*).*/1/p" "$RESPONSE_FILE")let used_mb=$used/1024/1024echo -e "Used: $used_mb Mb"let free_mb=($quota-$used)/1024/1024echo -e "Free: $free_mb Mb"echo ""elseprint "FAILED
"ERROR_STATUS=1fi}#Account unlinkfunction db_unlink{echo -ne "Are you sure you want unlink this script from your Dropbox account? [y/n]"read answerif [[ $answer == "y" ]]; thenrm -fr "$CONFIG_FILE"echo -ne "DONE
"fi}#Delete a remote file#$1 = Remote file to deletefunction db_delete{local FILE_DST=$(normalize_path "$1")print " > Deleting "$FILE_DST"... "$CURL_BIN $CURL_ACCEPT_CERTIFICATES -s --show-error --globoff -i -o "$RESPONSE_FILE" --data "oauth_consumer_key=$APPKEY&oauth_token=$OAUTH_ACCESS_TOKEN&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26$OAUTH_ACCESS_TOKEN_SECRET&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM&root=$ACCESS_LEVEL&path=$(urlencode "$FILE_DST")" "$API_DELETE_URL" 2> /dev/nullcheck_http_response#Checkif grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; thenprint "DONE
"elseprint "FAILED
"ERROR_STATUS=1fi}#Move/Rename a remote file#$1 = Remote file to rename or move#$2 = New file name or locationfunction db_move{local FILE_SRC=$(normalize_path "$1")local FILE_DST=$(normalize_path "$2")TYPE=$(db_stat "$FILE_DST")#If the destination it"s a directory, the source will be moved into itif [[ $TYPE == "DIR" ]]; thenlocal filename=$(basename "$FILE_SRC")FILE_DST=$(normalize_path "$FILE_DST/$filename")fiprint " > Moving "$FILE_SRC" to "$FILE_DST" ... "$CURL_BIN $CURL_ACCEPT_CERTIFICATES -s --show-error --globoff -i -o "$RESPONSE_FILE" --data "oauth_consumer_key=$APPKEY&oauth_token=$OAUTH_ACCESS_TOKEN&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26$OAUTH_ACCESS_TOKEN_SECRET&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM&root=$ACCESS_LEVEL&from_path=$(urlencode "$FILE_SRC")&to_path=$(urlencode "$FILE_DST")" "$API_MOVE_URL" 2> /dev/nullcheck_http_response#Checkif grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; thenprint "DONE
"elseprint "FAILED
"ERROR_STATUS=1fi}#Copy a remote file to a remote location#$1 = Remote file to rename or move#$2 = New file name or locationfunction db_copy{local FILE_SRC=$(normalize_path "$1")local FILE_DST=$(normalize_path "$2")TYPE=$(db_stat "$FILE_DST")#If the destination it"s a directory, the source will be copied into itif [[ $TYPE == "DIR" ]]; thenlocal filename=$(basename "$FILE_SRC")FILE_DST=$(normalize_path "$FILE_DST/$filename")fiprint " > Copying "$FILE_SRC" to "$FILE_DST" ... "$CURL_BIN $CURL_ACCEPT_CERTIFICATES -s --show-error --globoff -i -o "$RESPONSE_FILE" --data "oauth_consumer_key=$APPKEY&oauth_token=$OAUTH_ACCESS_TOKEN&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26$OAUTH_ACCESS_TOKEN_SECRET&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM&root=$ACCESS_LEVEL&from_path=$(urlencode "$FILE_SRC")&to_path=$(urlencode "$FILE_DST")" "$API_COPY_URL" 2> /dev/nullcheck_http_response#Checkif grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; thenprint "DONE
"elseprint "FAILED
"ERROR_STATUS=1fi}#Create a new directory#$1 = Remote directory to createfunction db_mkdir{local DIR_DST=$(normalize_path "$1")print " > Creating Directory "$DIR_DST"... "$CURL_BIN $CURL_ACCEPT_CERTIFICATES -s --show-error --globoff -i -o "$RESPONSE_FILE" --data "oauth_consumer_key=$APPKEY&oauth_token=$OAUTH_ACCESS_TOKEN&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26$OAUTH_ACCESS_TOKEN_SECRET&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM&root=$ACCESS_LEVEL&path=$(urlencode "$DIR_DST")" "$API_MKDIR_URL" 2> /dev/nullcheck_http_response#Checkif grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; thenprint "DONE
"elif grep -q "^HTTP/1.1 403 Forbidden" "$RESPONSE_FILE"; thenprint "ALREADY EXISTS
"elseprint "FAILED
"ERROR_STATUS=1fi}#List remote directory#$1 = Remote directoryfunction db_list{local DIR_DST=$(normalize_path "$1")print " > Listing "$DIR_DST"... "$CURL_BIN $CURL_ACCEPT_CERTIFICATES -s --show-error --globoff -i -o "$RESPONSE_FILE" "$API_METADATA_URL/$ACCESS_LEVEL/$(urlencode "$DIR_DST")?oauth_consumer_key=$APPKEY&oauth_token=$OAUTH_ACCESS_TOKEN&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26$OAUTH_ACCESS_TOKEN_SECRET&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM" 2> /dev/nullcheck_http_response#Checkif grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; thenlocal IS_DIR=$(sed -n "s/^(.*)"contents":.[.*/1/p" "$RESPONSE_FILE")#It"s a directoryif [[ $IS_DIR != "" ]]; thenprint "DONE
"#Extracting directory content [...]#and replacing "}, {" with "}
{"#I don"t like this piece of code... but seems to be the only way to do this with SED, writing a portable code...local DIR_CONTENT=$(sed -n "s/.*: [{(.*)/1/p" "$RESPONSE_FILE" | sed "s/}, *{/}{/g")#Converting escaped quotes to unicode formatecho "$DIR_CONTENT" | sed "s/\"/\u0022/" > "$TEMP_FILE"#Extracting files and subfoldersrm -fr "$RESPONSE_FILE"while read -r line; dolocal FILE=$(echo "$line" | sed -n "s/.*"path": *"([^"]*)".*/1/p")local IS_DIR=$(echo "$line" | sed -n "s/.*"is_dir": *([^,]*).*/1/p")local SIZE=$(echo "$line" | sed -n "s/.*"bytes": *([0-9]*).*/1/p")echo -e "$FILE:$IS_DIR;$SIZE" >> "$RESPONSE_FILE"done < "$TEMP_FILE"#Looking for the biggest file size#to calculate the padding to uselocal padding=0while read -r line; dolocal FILE=${line%:*}local META=${line##*:}local SIZE=${META#*;}if [[ ${#SIZE} -gt $padding ]]; thenpadding=${#SIZE}fidone < "$RESPONSE_FILE"#For each entry, printing directories...while read -r line; dolocal FILE=${line%:*}local META=${line##*:}local TYPE=${META%;*}local SIZE=${META#*;}#Removing unneeded /FILE=${FILE##*/}if [[ $TYPE != "false" ]]; thenFILE=$(echo -e "$FILE")$PRINTF " [D] %-${padding}s %s
" "$SIZE" "$FILE"fidone < "$RESPONSE_FILE"#For each entry, printing files...while read -r line; dolocal FILE=${line%:*}local META=${line##*:}local TYPE=${META%;*}local SIZE=${META#*;}#Removing unneeded /FILE=${FILE##*/}if [[ $TYPE == "false" ]]; thenFILE=$(echo -e "$FILE")$PRINTF " [F] %-${padding}s %s
" "$SIZE" "$FILE"fidone < "$RESPONSE_FILE"#It"s a fileelseprint "FAILED: $DIR_DST is not a directory!
"ERROR_STATUS=1fielseprint "FAILED
"ERROR_STATUS=1fi}#Share remote file#$1 = Remote filefunction db_share{local FILE_DST=$(normalize_path "$1")$CURL_BIN $CURL_ACCEPT_CERTIFICATES -s --show-error --globoff -i -o "$RESPONSE_FILE" "$API_SHARES_URL/$ACCESS_LEVEL/$(urlencode "$FILE_DST")?oauth_consumer_key=$APPKEY&oauth_token=$OAUTH_ACCESS_TOKEN&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26$OAUTH_ACCESS_TOKEN_SECRET&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM&short_url=false" 2> /dev/nullcheck_http_response#Checkif grep -q "^HTTP/1.1 200 OK" "$RESPONSE_FILE"; thenprint " > Share link: "echo $(sed -n "s/.*"url": "([^"]*).*/1/p" "$RESPONSE_FILE")elseprint "FAILED
"ERROR_STATUS=1fi}#################### SETUP #####################CHECKING FOR AUTH FILEif [[ -e $CONFIG_FILE ]]; then#Loading data... and change old format config if necesary.source "$CONFIG_FILE" 2>/dev/null || {sed -i"" "s/:/=/" "$CONFIG_FILE" && source "$CONFIG_FILE" 2>/dev/null}#Checking the loaded dataif [[ $APPKEY == "" || $APPSECRET == "" || $OAUTH_ACCESS_TOKEN_SECRET == "" || $OAUTH_ACCESS_TOKEN == "" ]]; thenecho -ne "Error loading data from $CONFIG_FILE...
"echo -ne "It is recommended to run $0 unlink
"remove_temp_filesexit 1fi#Back compatibility with previous Dropbox Uploader versionsif [[ $ACCESS_LEVEL == "" ]]; thenACCESS_LEVEL="dropbox"fi#NEW SETUP...elseecho -ne "
This is the first time you run this script.
"echo -ne " 1) Open the following URL in your Browser, and log in using your account: $APP_CREATE_URL
"echo -ne " 2) Click on "Create App", then select "Dropbox API app"
"echo -ne " 3) Select "Files and datastores"
"echo -ne " 4) Now go on with the configuration, choosing the app permissions and access restrictions to your DropBox folder
"echo -ne " 5) Enter the "App Name" that you prefer (e.g. MyUploader$RANDOM$RANDOM$RANDOM)
"echo -ne " Now, click on the "Create App" button.
"echo -ne " When your new App is successfully created, please type the
"echo -ne " App Key, App Secret and the Permission type shown in the confirmation page:
"#Getting the app key and secret from the userwhile (true); doecho -n " # App key: "read APPKEYecho -n " # App secret: "read APPSECRETecho -n " # Permission type, App folder or Full Dropbox [a/f]: "read ACCESS_LEVELif [[ $ACCESS_LEVEL == "a" ]]; thenACCESS_LEVEL="sandbox"ACCESS_MSG="App Folder"elseACCESS_LEVEL="dropbox"ACCESS_MSG="Full Dropbox"fiecho -ne "
> App key is $APPKEY, App secret is $APPSECRET and Access level is $ACCESS_MSG. Looks ok? [y/n]: "read answerif [[ $answer == "y" ]]; thenbreak;fidone#TOKEN REQUESTSecho -ne "
> Token request... "$CURL_BIN $CURL_ACCEPT_CERTIFICATES -s --show-error --globoff -i -o "$RESPONSE_FILE" --data "oauth_consumer_key=$APPKEY&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM" "$API_REQUEST_TOKEN_URL" 2> /dev/nullcheck_http_responseOAUTH_TOKEN_SECRET=$(sed -n "s/oauth_token_secret=([a-z A-Z 0-9]*).*/1/p" "$RESPONSE_FILE")OAUTH_TOKEN=$(sed -n "s/.*oauth_token=([a-z A-Z 0-9]*)/1/p" "$RESPONSE_FILE")if [[ $OAUTH_TOKEN != "" && $OAUTH_TOKEN_SECRET != "" ]]; thenecho -ne "OK
"elseecho -ne " FAILED
Please, check your App key and secret...
"remove_temp_filesexit 1fiwhile (true); do#USER AUTHecho -ne "
Please open the following URL in your browser, and allow Dropbox Uploader
"echo -ne " to access your DropBox folder:
--> ${API_USER_AUTH_URL}?oauth_token=$OAUTH_TOKEN
"echo -ne "
Press enter when done...
"read#API_ACCESS_TOKEN_URLecho -ne " > Access Token request... "$CURL_BIN $CURL_ACCEPT_CERTIFICATES -s --show-error --globoff -i -o "$RESPONSE_FILE" --data "oauth_consumer_key=$APPKEY&oauth_token=$OAUTH_TOKEN&oauth_signature_method=PLAINTEXT&oauth_signature=$APPSECRET%26$OAUTH_TOKEN_SECRET&oauth_timestamp=$(utime)&oauth_nonce=$RANDOM" "$API_ACCESS_TOKEN_URL" 2> /dev/nullcheck_http_responseOAUTH_ACCESS_TOKEN_SECRET=$(sed -n "s/oauth_token_secret=([a-z A-Z 0-9]*)&.*/1/p" "$RESPONSE_FILE")OAUTH_ACCESS_TOKEN=$(sed -n "s/.*oauth_token=([a-z A-Z 0-9]*)&.*/1/p" "$RESPONSE_FILE")OAUTH_ACCESS_UID=$(sed -n "s/.*uid=([0-9]*)/1/p" "$RESPONSE_FILE")if [[ $OAUTH_ACCESS_TOKEN != "" && $OAUTH_ACCESS_TOKEN_SECRET != "" && $OAUTH_ACCESS_UID != "" ]]; thenecho -ne "OK
"#Saving data in new format, compatible with source command.echo "APPKEY=$APPKEY" > "$CONFIG_FILE"echo "APPSECRET=$APPSECRET" >> "$CONFIG_FILE"echo "ACCESS_LEVEL=$ACCESS_LEVEL" >> "$CONFIG_FILE"echo "OAUTH_ACCESS_TOKEN=$OAUTH_ACCESS_TOKEN" >> "$CONFIG_FILE"echo "OAUTH_ACCESS_TOKEN_SECRET=$OAUTH_ACCESS_TOKEN_SECRET" >> "$CONFIG_FILE"echo -ne "
Setup completed!
"breakelseprint " FAILED
"ERROR_STATUS=1fidone;remove_temp_filesexit $ERROR_STATUSfi#################### START ####################COMMAND=${@:$OPTIND:1}ARG1=${@:$OPTIND+1:1}ARG2=${@:$OPTIND+2:1}let argnum=$#-$OPTIND#CHECKING PARAMS VALUEScase $COMMAND inupload)if [[ $argnum -lt 2 ]]; thenusagefiFILE_DST=${@:$#:1}for (( i=$OPTIND+1; i<$#; i++ )); doFILE_SRC=${@:$i:1}db_upload "$FILE_SRC" "/$FILE_DST"done;;download)if [[ $argnum -lt 1 ]]; thenusagefiFILE_SRC=$ARG1FILE_DST=$ARG2db_download "/$FILE_SRC" "$FILE_DST";;share)if [[ $argnum -lt 1 ]]; thenusagefiFILE_DST=$ARG1db_share "/$FILE_DST";;info)db_account_info;;delete|remove)if [[ $argnum -lt 1 ]]; thenusagefiFILE_DST=$ARG1db_delete "/$FILE_DST";;move|rename)if [[ $argnum -lt 2 ]]; thenusagefiFILE_SRC=$ARG1FILE_DST=$ARG2db_move "/$FILE_SRC" "/$FILE_DST";;copy)if [[ $argnum -lt 2 ]]; thenusagefiFILE_SRC=$ARG1FILE_DST=$ARG2db_copy "/$FILE_SRC" "/$FILE_DST";;mkdir)if [[ $argnum -lt 1 ]]; thenusagefiDIR_DST=$ARG1db_mkdir "/$DIR_DST";;list)DIR_DST=$ARG1#Checking DIR_DSTif [[ $DIR_DST == "" ]]; thenDIR_DST="/"fidb_list "/$DIR_DST";;unlink)db_unlink;;*)if [[ $COMMAND != "" ]]; thenprint "Error: Unknown command: $COMMAND
"ERROR_STATUS=1fiusage;;esacremove_temp_filesexit $ERROR_STATUS第一次使用,这个脚本会给你指导,告诉你去哪里获得dropbox的 API key 。
因为只有配置好了 API key ,这样才能授权给脚本应用进入你的dropbox目录