Article original : How to use a Bash script to manage downloading and viewing files from an AWS S3 bucket
Comme vous pouvez le lire dans cet article, j'ai récemment eu des problèmes avec mon serveur de messagerie et j'ai décidé d'externaliser l'administration des e-mails vers le service Amazon Simple Email Service (SES).
Le problème avec cette solution était que j'avais configuré SES pour sauvegarder les nouveaux messages dans un bucket S3, et l'utilisation de la console de gestion AWS pour lire les fichiers dans les buckets S3 devient rapidement fastidieuse.
J'ai donc décidé d'écrire un script Bash pour automatiser le processus de téléchargement, de stockage approprié et de visualisation des nouveaux messages.
Bien que j'aie écrit ce script pour l'utiliser sur mon bureau Ubuntu Linux, il ne nécessiterait pas trop de modifications pour fonctionner sur un système macOS ou Windows 10 via Windows SubSystem for Linux.
Voici le script complet en une seule partie. Après avoir pris quelques instants pour l'examiner, je vais vous le détailler étape par étape.
#!/bin/bash
# Récupérer les nouveaux messages depuis S3 et les sauvegarder dans le répertoire tmpemails/ :
aws s3 cp \
--recursive \
s3://bucket-name/ \
/home/david/s3-emails/tmpemails/ \
--profile myaccount
# Définir les variables de localisation :
tmp_file_location=/home/david/s3-emails/tmpemails/*
base_location=/home/david/s3-emails/emails/
# Créer un nouveau répertoire pour stocker les messages du jour :
today=$(date +"%m_%d_%Y")
[[ -d ${base_location}/"$today" ]] || mkdir ${base_location}/"$today"
# Donner aux fichiers de messages des noms lisibles :
for FILE in $tmp_file_location
do
mv $FILE ${base_location}/${today}/email$(rand)
done
# Ouvrir les nouveaux fichiers dans Gedit :
for NEWFILE in ${base_location}/${today}/*
do
gedit $NEWFILE
done
Nous commencerons par la commande unique pour télécharger les messages actuellement présents dans mon bucket S3 (au fait, j'ai changé les noms du bucket et autres détails de système de fichiers et d'authentification pour protéger ma vie privée).
aws s3 cp \
--recursive \
s3://bucket-name/ \
/home/david/s3-emails/tmpemails/ \
--profile myaccount
Bien sûr, cela ne fonctionnera que si vous avez déjà installé et configuré l'AWS CLI pour votre système local. C'est le moment de le faire si ce n'est pas déjà fait.
La commande cp signifie "copier", --recursive indique à la CLI d'appliquer l'opération même à plusieurs objets, s3://bucket-name pointe vers mon bucket (le nom de votre bucket sera évidemment différent), la ligne /home/david... est l'adresse absolue du système de fichiers vers laquelle je souhaite que les messages soient copiés, et l'argument --profile indique à la CLI lequel de mes multiples comptes AWS je référence.
La section suivante définit deux variables qui me faciliteront grandement la spécification des emplacements du système de fichiers tout au long du script.
tmp_file_location=/home/david/s3-emails/tmpemails/*
base_location=/home/david/s3-emails/emails/
Remarquez comment la valeur de la variable _tmp_filelocation se termine par un astérisque. C'est parce que je veux faire référence aux fichiers dans ce répertoire, plutôt qu'au répertoire lui-même.
Je vais créer un nouveau répertoire permanent dans la hiérarchie .../emails/ pour faciliter la recherche de messages plus tard. Le nom de ce nouveau répertoire sera la date actuelle.
today=$(date +"%m_%d_%Y")
[[ -d ${base_location}/"$today" ]] || mkdir ${base_location}/"$today"
Je commence par créer une nouvelle variable shell nommée today qui sera remplie par la sortie de la commande date +"%m%d%Y". date elle-même produit la date/horodatage complet, mais ce qui suit ("%m%d%Y") édite cette sortie pour un format plus simple et plus lisible.
Je teste ensuite l'existence d'un répertoire utilisant ce nom - ce qui indiquerait que j'ai déjà reçu des e-mails ce jour-là et, par conséquent, qu'il n'est pas nécessaire de recréer le répertoire. Si un tel répertoire n'existe pas (||), alors mkdir le créera pour moi. Si vous n'exécutez pas ce test, votre commande pourrait retourner des messages d'erreur ennuyeux.
Puisque Amazon SES donne des noms laids et illisibles à chacun des messages qu'il dépose dans mon bucket S3, je vais maintenant les renommer dynamiquement tout en les déplaçant vers leur nouvel emplacement (dans le répertoire daté que je viens de créer).
for FILE in $tmp_file_location
do
mv $FILE ${base_location}/${today}/email$(rand)
done
La boucle for...do...done lira chacun des fichiers dans le répertoire représenté par la variable _$tmp_filelocation puis le déplacera vers le répertoire que je viens de créer (représenté par la variable _$baselocation en plus de la valeur actuelle de $today).
Dans le cadre de la même opération, je lui donnerai son nouveau nom, la chaîne "email" suivie d'un nombre aléatoire généré par la commande rand. Vous devrez peut-être installer un générateur de nombres aléatoires : ce sera apt install rand sur Ubuntu.
Une version antérieure du script créait des noms différenciés par des nombres séquentiels plus courts qui étaient incrémentés en utilisant une logique count=1...count=$((count+1)) dans la boucle for. Cela fonctionnait bien tant que je ne recevais pas plus d'un lot de messages le même jour. Si c'était le cas, les nouveaux messages écraseraient les anciens fichiers dans le répertoire de ce jour.
Je suppose qu'il est mathématiquement possible que ma commande rand puisse attribuer des nombres qui se chevauchent à deux fichiers, mais étant donné que la plage par défaut utilisée par rand est comprise entre 1 et 32 576, c'est un risque que je suis prêt à prendre.
À ce stade, il devrait y avoir des fichiers dans le nouveau répertoire avec des noms comme email3039, email25343, etc. pour chacun des nouveaux messages que j'ai reçus.
L'exécution de la commande tree sur mon propre système me montre que cinq messages ont été sauvegardés dans mon répertoire 02_27_2020, et un de plus dans 02_28_2020 (ces fichiers ont été générés en utilisant l'ancienne version de mon script, donc ils sont numérotés séquentiellement).
Il n'y a actuellement aucun fichier dans tmpemails - c'est parce que la commande mv déplace les fichiers vers leur nouvel emplacement, sans laisser de trace.
$ tree
.
├── emails
│ ├── 02_27_2020
│ │ ├── email1
│ │ ├── email2
│ │ ├── email3
│ │ ├── email4
│ │ ├── email5
│ └── 02_28_2020
│ └── email1
└── tmpemails
La section finale du script ouvre chaque nouveau message dans mon éditeur de texte de bureau préféré (Gedit). Il utilise une boucle for...do...done similaire, lisant cette fois les noms de chaque fichier dans le nouveau répertoire (référencé en utilisant la commande "today") puis ouvrant le fichier dans Gedit. Remarquez l'astérisque que j'ai ajouté à la fin de l'emplacement du répertoire.
for NEWFILE in ${base_location}/${today}/*
do
gedit $NEWFILE
done
Il reste encore une chose à faire. Si je ne nettoie pas mon bucket S3, il téléchargera tous les messages accumulés à chaque fois que j'exécuterai le script. Cela rendra la gestion de plus en plus difficile.
Donc, après avoir téléchargé avec succès mes nouveaux messages, j'exécute ce court script pour supprimer tous les fichiers dans le bucket :
#!/bin/bash
# Supprimer tous les e-mails existants
aws s3 rm --recursive s3://bucket-name/ --profile myaccount