Tải tệp lên tài khoản S3 từ dòng lệnh Linux


74

Tôi đã có một số tệp lớn trong tài khoản lưu trữ Linux mà tôi cần tải lên tài khoản S3. Tôi không muốn tải chúng xuống trước và sau đó tải chúng lên S3.

Có cách nào tôi có thể "tải lên" nó thông qua dòng lệnh Linux không? Hoặc tôi có thể truy cập nó thông qua một trang web làm việc với Lynx không?

Câu trả lời:


30

S3cmd làm những gì bạn muốn. Tải lên và tải xuống các tệp, đồng bộ hóa thư mục và tạo các nhóm.

S3cmd là một công cụ dòng lệnh và ứng dụng khách miễn phí để tải lên, truy xuất và quản lý dữ liệu trong Amazon S3 và các nhà cung cấp dịch vụ lưu trữ đám mây khác sử dụng giao thức S3, như Google Cloud Storage hoặc Dreamhost DreamObjects. Nó phù hợp nhất cho người dùng quyền lực đã quen thuộc với các chương trình dòng lệnh. Nó cũng lý tưởng cho các tập lệnh bó và sao lưu tự động lên S3, được kích hoạt từ cron, v.v.


hoạt động như một lá bùa!
siliconpi

97

Amazon cũng cung cấp các công cụ CLI của riêng họ.

Từ http://aws.amazon.com/cli/

Sử dụng cú pháp quen thuộc, bạn có thể xem nội dung của các thùng S3 trong danh sách dựa trên thư mục.

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

Bạn có thể thực hiện tải lên đệ quy và tải xuống nhiều tệp trong một lệnh cấp thư mục. AWS CLI sẽ chạy các chuyển khoản này song song để tăng hiệu suất.

$ 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
...

Lệnh đồng bộ hóa giúp dễ dàng đồng bộ hóa nội dung của thư mục cục bộ với một bản sao trong nhóm S3.

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

Tài liệu cho các lệnh liên quan đến tập tin ở đây .


5
Câu trả lời đầy đủ nhất! :)
SergioFilhow

26

Nếu bạn không thể (có lẽ bạn đang sử dụng máy chủ chung) hoặc không muốn cài đặt các công cụ bổ sung, có thể chỉ cần sử dụng bash, curl và 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ưu ý rằng tôi đã sửa đổi tập lệnh này từ tập lệnh trong liên kết trên. Tôi đã thêm -Ltùy chọn vì AWS có thể chèn chuyển hướng vào đó. Các -Ltùy chọn sẽ theo chuyển hướng cho bạn.

Một cảnh báo khác. Điều này sẽ không hoạt động đối với các tệp lớn hơn 5GB. Những yêu cầu tải lên nhiều phần sẽ yêu cầu một kịch bản phức tạp hơn.


12

Một tập lệnh shell tương thích POSIX chỉ yêu cầu openssl, curl và sed; hỗ trợ AWS Chữ ký Phiên bản 4, được yêu cầu cho khu vực eu-central-1(Frankfurt) và được khuyến nghị cho những người khác:

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}"

Lưu ý, tập lệnh sẽ kích hoạt phía máy chủ

Mã hóa AES256 theo mặc định.


Đối với các công cụ tìm kiếm: Đây là giải pháp chính xác cho eu-centre-1 và nói chung nếu bạn gặp lỗiThe authorization mechanism you have provided is not supported. Please use AWS4-HMAC-SHA256
Steen

3

Ngoài ra, bạn có thể thử https://github.com/minio/mc

mccung cấp các công cụ tối thiểu để làm việc với hệ thống lưu trữ và hệ thống tệp đám mây tương thích Amazon S3. Nó có các tính năng như tải lên có thể tiếp tục, thanh tiến trình, sao chép song song. mcđược viết bằng Golang và được phát hành theo giấy phép Apache v2.


Đây là một câu trả lời tuyệt vời. Tôi không nhất thiết muốn làm điều đó trong bash, vì các câu trả lời (tốt) khác đang gợi ý. Tôi chỉ không muốn cài đặt tất cả các phụ thuộc mà awscli yêu cầu.
Michael Barton

1

Tôi đã thấy các ràng buộc AWS của Python trong botogói ( pip install boto) hữu ích cho việc tải dữ liệu lên S3.

Kịch bản sau đây có thể được gọi như: python script_name.py "sub_bucket_name" "*.zip"trong đó sub_bucket_namechỉ ra tên của thư mục mà các tệp sẽ được lưu trữ trong S3 và *.ziplà đường dẫn toàn cục chỉ định một hoặc nhiều tệp sẽ được tải lên:

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.