web-dev-qa-db-fra.com

Comment cp fichier uniquement s'il n'existe pas, lancer une erreur sinon?

aws s3 cp "dist/myfile" "s3://my-bucket/production/myfile"

Il copie toujours myfile vers s3 - Je voudrais copier le fichier UNIQUEMENT s'il n'existe pas, sinon, lancez une erreur. Comment je peux le faire? Ou au moins comment utiliser awscli pour vérifier si le fichier existe?

27
user606521

Vous pouvez tester l'existence d'un fichier en répertoriant le fichier et en vérifiant s'il renvoie quelque chose. Par exemple:

aws s3 ls s3://bucket/file.txt | wc -l

Cela retournerait un zéro (pas de lignes) si le fichier n'existe pas.


Si vous ne souhaitez copier un fichier que s'il n'existe pas , essayez le sync commande , par exemple:

aws s3 sync . s3://bucket/ --exclude '*' --include 'file.txt'

Cela synchronisera le fichier local avec l'objet distant, en le copiant uniquement s'il n'existe pas ou si le fichier local est différent de l'objet distant.

32
John Rotenstein

Il s'avère donc que "aws s3 sync" ne fait pas de fichiers, seulement des répertoires. Si vous lui donnez un fichier, vous obtenez un comportement ... intéressant ... car il traite tout ce que vous lui donnez comme un répertoire et jette une barre oblique dessus. Au moins aws-cli/1.6.7 Python/2.7.5 Darwin/13.4.0.

    %% date > test.txt
    %% aws s3 sync test.txt s3://bucket/test.txt
    warning: Skipping file /Users/draistrick/aws/test.txt/. File does not exist.

Donc, si vous voulez vraiment, vraiment, synchroniser un fichier (ne télécharger que s'il existe et si la somme de contrôle correspond), vous pouvez le faire:

    file="test.txt"
    aws s3 sync --exclude '*' --include "$file" "$(dirname $file)" "s3://bucket/"

Notez l'ordre d'exclusion/d'inclusion - si vous inversez cela, il n'inclura rien. Et votre chemin source et d'inclusion doit avoir un bon sens autour de leur correspondance, donc peut-être qu'un fichier $ (nom de base $) est nécessaire pour --inclure si vous utilisez des chemins complets ... aws --debug s3 sync est votre ami ici pour voir comment les inclus s’évaluent.

Et n'oubliez pas que la cible est une clé de répertoire, pas une clé de fichier.

Voici un exemple de travail:

  %% file="test.txt"
  %% date >> $file
  %% aws s3 sync --exclude '*' --include "$file" "$(dirname $file)" "s3://bucket/"
  upload: ./test.txt to s3://bucket/test.txt/test.txt
  %% aws s3 sync --exclude '*' --include "$file" "$(dirname $file)" "s3://bucket/"
  %% date >> $file
  %% aws s3 sync --exclude '*' --include "$file" "$(dirname $file)" "s3://bucket/"
  upload: ./test.txt to s3://bucket/test.txt/test.txt

(maintenant, si seulement il y avait un moyen de demander à aws s3 de -just- valider la somme de contrôle, car il semble toujours faire des sommes de contrôle de style en plusieurs parties .. oh, peut-être quelques -dryrun et quelques grattage et synchronisation de sortie ..)

10
keen

Vous pouvez le faire en répertoriant et en copiant si et seulement si la liste réussit.

aws s3 ls "s3://my-bucket/production/myfile" || aws s3 cp "dist/myfile" "s3://my-bucket/production/myfile"

Modifier: && remplacé à || pour avoir l'effet souhaité si la liste échoue, copiez

3
aviggiano

AWS HACK

Vous pouvez exécuter la commande suivante pour déclencher ERREUR si le fichier existe déjà

  • Exécutez la commande aws s3 sync pour synchroniser le fichier avec s3, il retournera le chemin copié si le fichier n'existe pas ou il donnera une sortie vide s'il se ferme
  • Courir wc -c commande pour vérifier le nombre de caractères et générer une erreur si la sortie est nulle

com = $ (aws s3 sync dist/s3: // my-bucket/production/| wc -c); if [[$ com -ne 0]]; puis quittez 1; sinon quittez 0; Fi;

OR

#!/usr/bin/env bash
com=$(aws s3 sync dist s3://my-bucket/production/ | wc -c)
echo "hello $com"
if [[ $com -ne 0 ]]; then
echo "File already exists"
exit 1
else
echo "success"
exit 0
fi
0
anand tripathi