Linux 명령 행에서 S3 계정으로 파일 업로드


74

Linux 호스팅 계정에 S3 계정에 업로드해야하는 큰 파일이 여러 개 있습니다. 먼저 다운로드 한 다음 S3에 업로드하고 싶지 않습니다.

Linux 명령 행을 통해 "업로드"할 수있는 방법이 있습니까? 아니면 Lynx와 함께 작동하는 웹 사이트를 통해 액세스 할 수 있습니까?

답변:


30

S3cmd 는 원하는 것을 수행합니다. 파일 업로드 및 다운로드, 디렉토리 동기화 및 버킷 생성

S3cmd는 Amazon S3 및 S3 프로토콜을 사용하는 다른 클라우드 스토리지 서비스 공급자 (예 : Google Cloud Storage 또는 DreamHost DreamObjects)에서 데이터를 업로드, 검색 및 관리하기위한 무료 명령 줄 도구 및 클라이언트입니다. 명령 줄 프로그램에 익숙한 고급 사용자에게 가장 적합합니다. 또한 배치 스크립트 및 S3 로의 자동 백업, cron 등에서 트리거하는 데 이상적입니다.


매력처럼 작동합니다!
siliconpi

97

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

파일 관련 명령에 대한 설명서 는 여기에 있습니다 .


5
가장 완전한 답변! :)
SergioFilhow 8

26

공유 호스트에 있지 않거나 추가 도구를 설치하지 않으려는 경우 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}

위 링크에있는 스크립트에서이 스크립트를 수정했습니다. -LAWS가 리디렉션을 삽입 할 수 있기 때문에 옵션을 추가 했습니다. -L옵션은 당신을 위해 리디렉션을 따릅니다.

다른 하나의 경고. 5GB보다 큰 파일에는 작동하지 않습니다. 보다 복잡한 스크립트가 필요한 멀티 파트 업로드가 필요합니다.


12

openssl, curl 및 sed 만 필요한 POSIX 호환 쉘 스크립트. 리전 eu-central-1(프랑크푸르트)에 필요하고 다른 사용자에게 권장 되는 AWS 서명 버전 4 지원 :

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 암호화.


검색 엔진의 경우 : 이것은 eu-central-1에 대한 올바른 솔루션이며 일반적으로 오류가 발생하는 경우The authorization mechanism you have provided is not supported. Please use AWS4-HMAC-SHA256
Steen

3

또는 https://github.com/minio/mc 를 시도 할 수 있습니다

mcAmazon S3 호환 클라우드 스토리지 및 파일 시스템과 함께 작동하는 최소한의 도구를 제공합니다. 재개 가능한 업로드, 진행률 표시 줄, 병렬 복사와 같은 기능이 있습니다. mcGolang으로 작성되었으며 Apache 라이센스 v2로 출시되었습니다.


이것은 좋은 대답입니다. 다른 (좋은) 대답이 제안하는 것처럼 반드시 bash에서하고 싶지는 않습니다. awscli에 필요한 모든 종속성을 설치하고 싶지 않습니다.
Michael Barton

1

boto패키지 ( pip install boto) 에서 Python의 AWS 바인딩 이 S3에 데이터를 업로드하는 데 도움 이된다는 것을 알았습니다 .

다음과 같은 스크립트를 호출 할 수 있습니다. python script_name.py "sub_bucket_name" "*.zip"여기서 sub_bucket_nameS3에 파일을 저장해야하는 디렉토리의 이름을 나타내며 *.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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.