wake-up-neo.com

Wie erst cp-Datei, wenn es nicht existiert, sonst Fehler werfen?

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

Es kopiert immer myfile nach s3 - Ich möchte die Datei NUR kopieren, wenn sie nicht existiert, andernfalls einen Fehler auslösen. Wie kann ich es tun? Oder zumindest wie kann ich mit awscli prüfen, ob eine Datei existiert?

27
user606521

Sie können das Vorhandensein einer Datei testen, indem Sie die Datei auflisten und prüfen, ob sie etwas zurückgibt. Beispielsweise:

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

Dies würde eine Null (keine Zeilen) zurückgeben, wenn die Datei nicht existiert.


Wenn Sie eine Datei nur kopieren möchten, wenn sie nicht vorhanden ist, versuchen Sie es mit sync Befehl , zB:

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

Dadurch wird die lokale Datei mit dem Remote-Objekt synchronisiert und nur kopiert, wenn sie nicht vorhanden ist oder wenn sich die lokale Datei vom Remote-Objekt unterscheidet.

32
John Rotenstein

Es stellt sich also heraus, dass "aws s3 sync" keine Dateien, sondern nur Verzeichnisse ausführt. Wenn Sie ihm eine Datei geben, erhalten Sie ... interessantes ... Verhalten, da es alles behandelt, was Sie ihm geben, wie ein Verzeichnis und einen Schrägstrich darauf wirft. Zumindest 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.

Wenn Sie also wirklich nur eine Datei synchronisieren möchten (nur hochladen, wenn vorhanden und wenn die Prüfsumme übereinstimmt), können Sie dies tun:

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

Beachten Sie die Ausschluss-/Einschlussreihenfolge. Wenn Sie diese umkehren, wird nichts hinzugefügt. Und Ihr Quell- und Include-Pfad muss einen vernünftigen Ansatz haben. Vielleicht ist also ein $ (Basisname $ -Datei) angebracht, um --einschließen zu können, wenn Sie vollständige Pfade verwenden ... aws --debug s3 sync ist Ihr Freund hier um zu sehen, wie die Includes ausgewertet werden.

Und vergessen Sie nicht, dass das Ziel ein Verzeichnisschlüssel und kein Dateischlüssel ist.

Hier ist ein funktionierendes Beispiel:

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

(Wenn es nur eine Möglichkeit gäbe, aws s3 zu bitten, die Prüfsumme zu validieren, da es immer mehrteilige Prüfsummen zu geben scheint. Oh, vielleicht etwas --dryrun und etwas Output Scraping und Sync.)

10
keen

Sie können dies tun, indem Sie genau dann auflisten und kopieren, wenn die Liste erfolgreich ist.

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

Bearbeiten: ersetzt && zu || Um den gewünschten Effekt zu erzielen, kopieren Sie die Liste

3
aviggiano

AWS HACK

Sie können den folgenden Befehl ausführen, um ERROR auszulösen, wenn die Datei bereits vorhanden ist

  • Führen Sie den Befehl aws s3 sync aus, um die Datei mit s3 zu synchronisieren. Er gibt den kopierten Pfad zurück, wenn die Datei nicht vorhanden ist, oder gibt eine leere Ausgabe aus, wenn sie beendet wird
  • Lauf wc -c Befehl zum Überprüfen der Zeichenanzahl und Auslösen eines Fehlers, wenn die Ausgabe Null ist

com = $ (aws s3 sync dist/s3: // my-bucket/production/| wc -c); if [[$ com -ne 0]]; dann Ausfahrt 1; sonst Ausfahrt 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