Verwendung eines Bash-Skripts zum Verwalten des Herunterladens und Anzeigens von Dateien aus einem AWS S3-Bucket

Wie Sie in diesem Artikel lesen können, hatte ich kürzlich einige Probleme mit meinem E-Mail-Server und entschied mich, die E-Mail-Verwaltung an den Simple Email Service (SES) von Amazon auszulagern.

Das Problem bei dieser Lösung war, dass SES neue Nachrichten in einem S3-Bucket speichern musste und die Verwendung der AWS Management Console zum Lesen von Dateien in S3-Buckets sehr schnell veraltet ist.

Deshalb habe ich beschlossen, ein Bash-Skript zu schreiben, um das Herunterladen, ordnungsgemäße Speichern und Anzeigen neuer Nachrichten zu automatisieren.

Während ich dieses Skript für die Verwendung auf meinem Ubuntu Linux-Desktop geschrieben habe, würde es nicht zu viel Fummelei erfordern, damit es auf einem MacOS- oder Windows 10-System über Windows SubSystem für Linux funktioniert.

Hier ist das komplette Skript in einem Stück. Nachdem Sie sich einen Moment Zeit genommen haben, um es sich anzusehen, werde ich Sie Schritt für Schritt durch das Buch führen.

#!/bin/bash # Retrieve new messages from S3 and save to tmpemails/ directory: aws s3 cp \ --recursive \ s3://bucket-name/ \ /home/david/s3-emails/tmpemails/ \ --profile myaccount # Set location variables: tmp_file_location=/home/david/s3-emails/tmpemails/* base_location=/home/david/s3-emails/emails/ # Create new directory to store today's messages: today=$(date +"%m_%d_%Y") [[ -d ${base_location}/"$today" ]] || mkdir ${base_location}/"$today" # Give the message files readable names: for FILE in $tmp_file_location do mv $FILE ${base_location}/${today}/email$(rand) done # Open new files in Gedit: for NEWFILE in ${base_location}/${today}/* do gedit $NEWFILE done

Wir beginnen mit dem einzigen Befehl zum Herunterladen aller Nachrichten, die sich derzeit in meinem S3-Bucket befinden (ich habe übrigens die Namen des Buckets und anderer Dateisystem- und Authentifizierungsdetails geändert, um meine Privatsphäre zu schützen).

aws s3 cp \ --recursive \ s3://bucket-name/ \ /home/david/s3-emails/tmpemails/ \ --profile myaccount

Dies funktioniert natürlich nur, wenn Sie die AWS CLI bereits für Ihr lokales System installiert und konfiguriert haben. Jetzt ist die Zeit dafür, wenn Sie es noch nicht getan haben.

Der Befehl cp steht für "copy". --Recursive weist die CLI an, die Operation auch auf mehrere Objekte anzuwenden. S3 : // Bucket-Name zeigt auf meinen Bucket (Ihr Bucket-Name wird offensichtlich anders sein), das / home / david ... Zeile ist die absolute Dateisystemadresse, an die die Nachrichten kopiert werden sollen, und das Argument --profile teilt der CLI mit, auf welches meiner mehreren AWS-Konten ich mich beziehe.

Im nächsten Abschnitt werden zwei Variablen festgelegt, die es mir erheblich erleichtern, die Speicherorte des Dateisystems im Rest des Skripts anzugeben.

tmp_file_location=/home/david/s3-emails/tmpemails/* base_location=/home/david/s3-emails/emails/

Beachten Sie, wie der Wert der Variablen tmp_file_location mit einem Sternchen endet. Das liegt daran, dass ich auf die Dateien in diesem Verzeichnis und nicht auf das Verzeichnis selbst verweisen möchte .

Ich werde ein neues permanentes Verzeichnis in der Hierarchie ... / emails / erstellen, damit ich später leichter Nachrichten finden kann. Der Name dieses neuen Verzeichnisses ist das aktuelle Datum.

today=$(date +"%m_%d_%Y") [[ -d ${base_location}/"$today" ]] || mkdir ${base_location}/"$today"

Ich erstelle zuerst eine neue Shell-Variable mit dem Namen heute , die mit der Ausgabe des Befehls date + "% m_% d_% Y" gefüllt wird. Das Datum selbst gibt das vollständige Datum / den vollständigen Zeitstempel aus. Im Folgenden ( "% m_% d_% Y" ) wird diese Ausgabe jedoch in einem einfacheren und besser lesbaren Format bearbeitet.

Ich teste dann die Existenz eines direkt unter Verwendung dieses Namens - was darauf hinweist, dass ich an diesem Tag bereits E-Mails erhalten habe und daher das Verzeichnis nicht neu erstellt werden muss. Wenn ein solches Verzeichnis nicht existiert (||), erstellt mkdir es für mich. Wenn Sie diesen Test nicht ausführen, kann Ihr Befehl störende Fehlermeldungen zurückgeben.

Da Amazon SES jeder Nachricht, die in meinem S3-Bucket abgelegt wird, hässliche und unlesbare Namen gibt, benenne ich sie jetzt dynamisch um und verschiebe sie gleichzeitig in ihr neues Zuhause (in dem soeben erstellten datierten Verzeichnis). .

for FILE in $tmp_file_location do mv $FILE ${base_location}/${today}/email$(rand) done

Die for ... do ... done- Schleife liest jede der Dateien in dem Verzeichnis, das durch die Variable $ tmp_file_location dargestellt wird, und verschiebt sie dann in das Verzeichnis, das ich gerade erstellt habe (dargestellt durch die Variable $ base_location zusätzlich zum aktuellen Wert von $ heute ).

Als Teil derselben Operation gebe ich ihm seinen neuen Namen, die Zeichenfolge " email ", gefolgt von einer Zufallszahl, die vom Befehl rand generiert wird . Möglicherweise müssen Sie einen Zufallszahlengenerator installieren: Das ist passend, um Rand unter Ubuntu zu installieren .

In einer früheren Version des Skripts wurden Namen erstellt, die sich durch kürzere fortlaufende Nummern unterscheiden, die mithilfe einer count = 1 ... count = $ ((count + 1)) - Logik innerhalb der for- Schleife inkrementiert wurden . Das hat gut funktioniert, solange ich nicht mehr als einen Stapel Nachrichten am selben Tag erhalten habe. Wenn ich das tun würde, würden die neuen Nachrichten ältere Dateien im Verzeichnis dieses Tages überschreiben.

Ich denke, es ist mathematisch möglich, dass mein Rand- Befehl zwei Dateien überlappende Zahlen zuweist, aber da der Standardbereich, den Rand verwendet, zwischen 1 und 32.576 liegt, ist dies ein Risiko, das ich eingehen möchte.

Zu diesem Zeitpunkt sollten sich im neuen Verzeichnis Dateien mit Namen wie email3039, email25343 usw. für jede der neuen Nachrichten befinden, die mir gesendet wurden.

Das Ausführen des Befehls tree auf meinem eigenen System zeigt mir, dass fünf Nachrichten in meinem Verzeichnis 02_27_2020 und eine weitere in 02_28_2020 gespeichert wurden (diese Dateien wurden mit der älteren Version meines Skripts generiert, daher sind sie fortlaufend nummeriert).

Derzeit befinden sich keine Dateien in tmpemails. Dies liegt daran, dass der Befehl mv Dateien an ihren neuen Speicherort verschiebt und nichts zurücklässt .

$ tree . ├── emails │   ├── 02_27_2020 │   │   ├── email1 │   │   ├── email2 │   │   ├── email3 │   │   ├── email4 │   │   ├── email5 │   └── 02_28_2020 │   └── email1 └── tmpemails

Der letzte Abschnitt des Skripts öffnet jede neue Nachricht in meinem bevorzugten Desktop-Texteditor (Gedit). Es wird eine ähnliche for ... do ... done- Schleife verwendet, die diesmal die Namen jeder Datei im neuen Verzeichnis liest (mit dem Befehl " today " referenziert ) und dann die Datei in Gedit öffnet. Beachten Sie das Sternchen, das ich am Ende des Verzeichnisses hinzugefügt habe.

for NEWFILE in ${base_location}/${today}/* do gedit $NEWFILE done

Es gibt noch etwas zu tun. Wenn ich meinen S3-Bucket nicht bereinige, werden bei jeder Ausführung des Skripts alle gesammelten Nachrichten heruntergeladen. Das wird es zunehmend schwieriger machen, damit umzugehen.

Nachdem ich meine neuen Nachrichten erfolgreich heruntergeladen habe, führe ich dieses kurze Skript aus, um alle Dateien im Bucket zu löschen:

#!/bin/bash # Delete all existing emails aws s3 rm --recursive s3://bucket-name/ --profile myaccount