75 votes

Est-il possible de copier tous les fichiers d'un compartiment S3 à un autre avec s3cmd?

Je suis assez content de s3cmd, mais il y a un problème: comment copier tous les fichiers d'un compartiment S3 à un autre? Est-ce même possible?

EDIT: J'ai trouvé un moyen de copier des fichiers entre des seaux en utilisant Python avec boto:

 from boto.s3.connection import S3Connection

def copyBucket(srcBucketName, dstBucketName, maxKeys = 100):
  conn = S3Connection(awsAccessKey, awsSecretKey)

  srcBucket = conn.get_bucket(srcBucketName);
  dstBucket = conn.get_bucket(dstBucketName);

  resultMarker = ''
  while True:
    keys = srcBucket.get_all_keys(max_keys = maxKeys, marker = resultMarker)

    for k in keys:
      print 'Copying ' + k.key + ' from ' + srcBucketName + ' to ' + dstBucketName

      t0 = time.clock()
      dstBucket.copy_key(k.key, srcBucketName, k.key)
      print time.clock() - t0, ' seconds'

    if len(keys) < maxKeys:
      print 'Done'
      break

    resultMarker = keys[maxKeys - 1].key
 

La synchronisation est presque aussi simple que la copie. Il existe des champs pour ETag, taille et dernière modification disponibles pour les clés.

Peut-être que cela aide les autres aussi.

90voto

amit_saxena Points 2434

s3cmd sync s3://from/this/bucket/ s3://to/this/bucket/

Pour les options disponibles, veuillez utiliser: $s3cmd --help

44voto

adamp Points 196

AWS CLI semble parfaitement faire le travail et présente l'avantage d'être un outil officiellement pris en charge.

 aws s3 sync s3://mybucket s3://backup-mybucket
 

http://docs.aws.amazon.com/cli/latest/reference/s3/sync.html

29voto

mdahlman Points 5700

La réponse avec le plus upvotes que je vous écris, c'est celui-ci:

s3cmd sync s3://from/this/bucket s3://to/this/bucket

C'est une réponse utile. Mais parfois, la synchronisation n'est pas ce dont vous avez besoin (il supprime les fichiers, etc.). Il m'a fallu beaucoup de temps pour comprendre ce non script alternative de simplement copier plusieurs fichiers entre des seaux. (OK, dans le cas illustré ci-dessous, il n'est pas entre les seaux. Il est entre de pas-vraiment-dossiers, mais il fonctionne entre les seaux de la même manière.)

# Slightly verbose, slightly unintuitive, very useful:
s3cmd cp --recursive --exclude=* --include=file_prefix* s3://semarchy-inc/source1/ s3://semarchy-inc/target/

Explication de la commande ci-dessus:

  • –récursive
    Dans mon esprit, mon exigence n'est pas récursive. Je veux simplement plusieurs fichiers. Mais récursive dans ce contexte dit juste s3cmd cp à gérer plusieurs fichiers. Grand.
  • –exclure
    C'est une drôle de façon de penser le problème. Commencez en sélectionnant de manière récursive tous les fichiers. Ensuite, exclure tous les fichiers. Attendez, quoi?
  • –inclure
    Maintenant, nous sommes en train de parler. Indiquer le préfixe de fichier (ou un suffixe, ou quel que soit le motif) que vous souhaitez inclure.
    s3://sourceBucket/ s3://targetBucket/
    Cette partie est assez intuitif. Si, techniquement, il semble enfreindre l'exemple documenté de s3cmd d'aide qui indique qu'un objet source doit être spécifié:
    s3cmd cp s3://BUCKET1/OBJECT1 s3://BUCKET2[/OBJECT2]

8voto

Paul Points 101

J'avais besoin de copier un très grand seau, j'ai donc adapté le code de la question à une version multi-thread et l'a mis sur GitHub.

https://github.com/paultuckey/s3-bucket-to-bucket-copy-py

2voto

Adam Points 2669

Merci. J'utilise une version légèrement modifiée, dans laquelle je ne copie que des fichiers qui n'existent pas ou dont la taille est différente, et vérifie la destination si la clé existe dans la source. J'ai trouvé cela un peu plus rapide pour préparer l'environnement de test:

 def botoSyncPath(path):
    """
       Sync keys in specified path from source bucket to target bucket.
    """
    try:
        conn = S3Connection(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
        srcBucket = conn.get_bucket(AWS_SRC_BUCKET)
        destBucket = conn.get_bucket(AWS_DEST_BUCKET)
        for key in srcBucket.list(path):
            destKey = destBucket.get_key(key.name)
            if not destKey or destKey.size != key.size:
                key.copy(AWS_DEST_BUCKET, key.name)

        for key in destBucket.list(path):
            srcKey = srcBucket.get_key(key.name)
            if not srcKey:
                key.delete()
    except:
        return False
    return True
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X