سؤال تحميل الملفات إلى حساب S3 من سطر أوامر Linux


لدي العديد من الملفات الكبيرة في حساب Linux المستضاف الذي أحتاج إلى تحميله إلى حساب S3 الخاص بي. لا أريد تنزيلها أولاً ثم تحميلها إلى S3.

هل هناك طريقة يمكنني "تحميل" بها عبر سطر أوامر Linux؟ أو هل يمكنني الوصول إليه عبر موقع ويب يعمل مع Lynx؟


67
2018-05-06 07:51


الأصل




الأجوبة:


S3cmd يفعل ما تريد. تحميل وتنزيل الملفات ومزامنة الدلائل وإنشاء مجموعات.

S3cmd عبارة عن أداة سطر أوامر مجانية وعميل لتحميل واسترداد وإدارة البيانات في Amazon S3 وموفري خدمات التخزين السحابي الآخرين الذين يستخدمون بروتوكول S3 ، مثل Google Cloud Storage أو DreamHost DreamObjects. هو الأنسب لمستخدمي السلطة الذين هم على دراية ببرامج سطر الأوامر. كما أنه مثالي للبرامج النصية الدفعة والنسخ الاحتياطي التلقائي إلى S3 ، والتي يتم تشغيلها من cron ، إلخ.


28
2018-05-06 07:58



يعمل كالسحر! - siliconpi


يوفر Amazon أدوات CLI الخاصة به الآن أيضًا.

من عند http://aws.amazon.com/cli/

باستخدام صيغة مألوفة ، يمكنك عرض محتويات مجموعات S3 في قائمة مستندة إلى الدليل.

$ aws s3 ls s3://mybucket
      LastWriteTime     Length Name
      -------------     ------ ----
                           PRE myfolder/
2013-09-03 10:00:00       1234 myfile.txt
...

يمكنك إجراء عمليات التحميل والتكرار المتكررة لملفات متعددة في أمر واحد على مستوى المجلد. سيقوم AWS CLI بتشغيل هذه التحويلات بالتوازي لزيادة الأداء.

$ aws s3 cp myfolder s3://mybucket/myfolder --recursive
upload: myfolder/file1.txt to s3://mybucket/myfolder/file1.txt
upload: myfolder/subfolder/file1.txt to s3://mybucket/myfolder/subfolder/file1.txt
...

يعمل أمر sync على تسهيل مزامنة محتويات المجلد المحلي مع نسخة في مجموعة S3.

$ aws s3 sync myfolder s3://mybucket/myfolder --exclude *.tmp
upload: myfolder/newfile.txt to s3://mybucket/myfolder/newfile.txt
...

وثائق ل أوامر الملف ذات الصلة هنا.


88
2017-10-24 12:12



الجواب الأكثر اكتمالا! :) - SergioFilhow


إذا كنت لا تستطيع (ربما تكون على مضيف مشترك) أو لا ترغب في تثبيت أدوات إضافية ، فمن الممكن فقط استخدام bash و curl و openssl.

http://tmont.com/blargh/2014/1/uploading-to-s3-in-bash

file=/path/to/file/to/upload.tar.gz
bucket=your-bucket
resource="/${bucket}/${file}"
contentType="application/x-compressed-tar"
dateValue=`date -R`
stringToSign="PUT\n\n${contentType}\n${dateValue}\n${resource}"
s3Key=xxxxxxxxxxxxxxxxxxxx
s3Secret=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
signature=`echo -en ${stringToSign} | openssl sha1 -hmac ${s3Secret} -binary | base64`
curl -L -X PUT -T "${file}" \
  -H "Host: ${bucket}.s3.amazonaws.com" \
  -H "Date: ${dateValue}" \
  -H "Content-Type: ${contentType}" \
  -H "Authorization: AWS ${s3Key}:${signature}" \
  https://${bucket}.s3.amazonaws.com/${file}

لاحظ أنني قمت بتعديل هذا البرنامج النصي من الرابط الموجود في الرابط أعلاه. أضفت -L الخيار لأن AWS قد تقوم بإدخال إعادة توجيه هناك. ال -L سيتبع الخيار إعادة التوجيه نيابة عنك.

واحد آخر التحذير. لن يعمل ذلك مع الملفات التي يزيد حجمها عن 5 غيغابايت. تلك تتطلب تحميل متعدد الأجزاء يتطلب برنامجًا أكثر تعقيدًا.


26
2017-10-10 16:48





برنامج نصي shell متوافق مع POSIX يتطلب openssl و curl و sed فقط ؛ دعم الإصدار 4 من AWS Signature ، وهو مطلوب للمنطقة eu-central-1 (فرانكفورت) والموصى بها للآخرين:

https://gist.github.com/vszakats/2917d28a951844ab80b1

#!/bin/sh -u

# To the extent possible under law, Viktor Szakats (vszakats.net)
# has waived all copyright and related or neighboring rights to this
# script.
# CC0 - https://creativecommons.org/publicdomain/zero/1.0/

# Upload a file to Amazon AWS S3 using Signature Version 4
#
# docs:
#    https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
#
# requires:
#    curl, openssl 1.x, GNU sed, LF EOLs in this file

fileLocal="${1:-example-local-file.ext}"
bucket="${2:-example-bucket}"
region="${3:-}"
storageClass="${4:-STANDARD}"  # or 'REDUCED_REDUNDANCY'

m_openssl() {
  if [ -f /usr/local/opt/openssl@1.1/bin/openssl ]; then
    /usr/local/opt/openssl@1.1/bin/openssl "$@"
  elif [ -f /usr/local/opt/openssl/bin/openssl ]; then
    /usr/local/opt/openssl/bin/openssl "$@"
  else
    openssl "$@"
  fi
}

m_sed() {
  if which gsed > /dev/null 2>&1; then
    gsed "$@"
  else
    sed "$@"
  fi
}

awsStringSign4() {
  kSecret="AWS4$1"
  kDate=$(printf         '%s' "$2" | m_openssl dgst -sha256 -hex -mac HMAC -macopt "key:${kSecret}"     2>/dev/null | m_sed 's/^.* //')
  kRegion=$(printf       '%s' "$3" | m_openssl dgst -sha256 -hex -mac HMAC -macopt "hexkey:${kDate}"    2>/dev/null | m_sed 's/^.* //')
  kService=$(printf      '%s' "$4" | m_openssl dgst -sha256 -hex -mac HMAC -macopt "hexkey:${kRegion}"  2>/dev/null | m_sed 's/^.* //')
  kSigning=$(printf 'aws4_request' | m_openssl dgst -sha256 -hex -mac HMAC -macopt "hexkey:${kService}" 2>/dev/null | m_sed 's/^.* //')
  signedString=$(printf  '%s' "$5" | m_openssl dgst -sha256 -hex -mac HMAC -macopt "hexkey:${kSigning}" 2>/dev/null | m_sed 's/^.* //')
  printf '%s' "${signedString}"
}

iniGet() {
  # based on: https://stackoverflow.com/questions/22550265/read-certain-key-from-certain-section-of-ini-file-sed-awk#comment34321563_22550640
  printf '%s' "$(m_sed -n -E "/\[$2\]/,/\[.*\]/{/$3/s/(.*)=[ \\t]*(.*)/\2/p}" "$1")"
}

# Initialize access keys

if [ -z "${AWS_CONFIG_FILE:-}" ]; then
  if [ -z "${AWS_ACCESS_KEY:-}" ]; then
    echo 'AWS_CONFIG_FILE or AWS_ACCESS_KEY/AWS_SECRET_KEY envvars not set.'
    exit 1
  else
    awsAccess="${AWS_ACCESS_KEY}"
    awsSecret="${AWS_SECRET_KEY}"
    awsRegion='us-east-1'
  fi
else
  awsProfile='default'

  # Read standard aws-cli configuration file
  # pointed to by the envvar AWS_CONFIG_FILE
  awsAccess="$(iniGet "${AWS_CONFIG_FILE}" "${awsProfile}" 'aws_access_key_id')"
  awsSecret="$(iniGet "${AWS_CONFIG_FILE}" "${awsProfile}" 'aws_secret_access_key')"
  awsRegion="$(iniGet "${AWS_CONFIG_FILE}" "${awsProfile}" 'region')"
fi

# Initialize defaults

fileRemote="${fileLocal}"

if [ -z "${region}" ]; then
  region="${awsRegion}"
fi

echo "Uploading" "${fileLocal}" "->" "${bucket}" "${region}" "${storageClass}"
echo "| $(uname) | $(m_openssl version) | $(m_sed --version | head -1) |"

# Initialize helper variables

httpReq='PUT'
authType='AWS4-HMAC-SHA256'
service='s3'
baseUrl=".${service}.amazonaws.com"
dateValueS=$(date -u +'%Y%m%d')
dateValueL=$(date -u +'%Y%m%dT%H%M%SZ')
if hash file 2>/dev/null; then
  contentType="$(file -b --mime-type "${fileLocal}")"
else
  contentType='application/octet-stream'
fi

# 0. Hash the file to be uploaded

if [ -f "${fileLocal}" ]; then
  payloadHash=$(m_openssl dgst -sha256 -hex < "${fileLocal}" 2>/dev/null | m_sed 's/^.* //')
else
  echo "File not found: '${fileLocal}'"
  exit 1
fi

# 1. Create canonical request

# NOTE: order significant in ${headerList} and ${canonicalRequest}

headerList='content-type;host;x-amz-content-sha256;x-amz-date;x-amz-server-side-encryption;x-amz-storage-class'

canonicalRequest="\
${httpReq}
/${fileRemote}

content-type:${contentType}
host:${bucket}${baseUrl}
x-amz-content-sha256:${payloadHash}
x-amz-date:${dateValueL}
x-amz-server-side-encryption:AES256
x-amz-storage-class:${storageClass}

${headerList}
${payloadHash}"

# Hash it

canonicalRequestHash=$(printf '%s' "${canonicalRequest}" | m_openssl dgst -sha256 -hex 2>/dev/null | m_sed 's/^.* //')

# 2. Create string to sign

stringToSign="\
${authType}
${dateValueL}
${dateValueS}/${region}/${service}/aws4_request
${canonicalRequestHash}"

# 3. Sign the string

signature=$(awsStringSign4 "${awsSecret}" "${dateValueS}" "${region}" "${service}" "${stringToSign}")

# Upload

curl -s -L --proto-redir =https -X "${httpReq}" -T "${fileLocal}" \
  -H "Content-Type: ${contentType}" \
  -H "Host: ${bucket}${baseUrl}" \
  -H "X-Amz-Content-SHA256: ${payloadHash}" \
  -H "X-Amz-Date: ${dateValueL}" \
  -H "X-Amz-Server-Side-Encryption: AES256" \
  -H "X-Amz-Storage-Class: ${storageClass}" \
  -H "Authorization: ${authType} Credential=${awsAccess}/${dateValueS}/${region}/${service}/aws4_request, SignedHeaders=${headerList}, Signature=${signature}" \
  "https://${bucket}${baseUrl}/${fileRemote}"

لاحظ ، فإن البرنامج النصي تمكين جانب الخادم

التشفير AES256 افتراضيا.


11
2017-12-26 01:55



لمحركات البحث: هذا هو الحل الصحيح لـ eu-central-1 وبشكل عام إذا ظهر لك الخطأ The authorization mechanism you have provided is not supported. Please use AWS4-HMAC-SHA256 - Steen


بدلا من ذلك يمكنك أن تجرب https://github.com/minio/mc 

mc يوفر الحد الأدنى من الأدوات للعمل مع التخزين السحابي ونظام التخزين السحابي Amazon S3. لديها ميزات مثل التحميلات القابلة للاستئناف ، شريط التقدم ، نسخة متوازية. mc هو مكتوب في Golang وأفرج عنه تحت رخصة أباتشي الإصدار 2.


3
2017-11-25 18:23



هذا هو الجواب كبيرة. لا أريد بالضرورة أن أفعل ذلك في bash ، كما تقترح الإجابات الأخرى (الجيدة). أنا لا أريد تثبيت جميع الاعتمادات التي يتطلبها awscli. - Michael Barton


لقد وجدت بايزون في ارتباطات AWS في boto صفقة (pip install boto) لتكون مفيدة لتحميل البيانات إلى S3.

يمكن استدعاء البرنامج النصي التالي مثل: python script_name.py "sub_bucket_name" "*.zip" أين sub_bucket_name يشير إلى اسم الدليل الذي يجب تخزين الملفات فيه في S3 و *.zip هو مسار عالمي يحدد ملفًا واحدًا أو أكثر ليتم تحميله:

import sys, glob, os, boto
from boto.s3.key import Key

def percent_cb(complete, total):
    sys.stdout.write('.')
    sys.stdout.flush()

id = '< your id here >'               # AWS Access Key ID
secret = '< your secret here >'       # AWS Secret Access Key
bucket_name = '< your bucket here >'  # Bucket wherein content will be stored
conn = boto.connect_s3(id, secret)    # Establish a connection to S3
bucket = conn.get_bucket(bucket_name, validate=False)  # Connect to bucket
k  = Key(bucket)                      # Connect to the bucket's key

for i in glob.glob(sys.argv[2]):      # Read in files to push to S3

        sub_bucket = sys.argv[1]  # Directory within bucket where files will be stored
        k.key = sub_bucket + "/" + os.path.basename(i) # Path each uploaded file will have on S3

        k.set_contents_from_filename(i, cb=percent_cb, num_cb=10)  # Push data to S3

        print 'Uploading %s to Amazon S3 bucket %s' % (i, bucket_name)  # Report status

1
2017-10-21 01:51