Cómo utilizar un script Bash para administrar la descarga y visualización de archivos desde un bucket de AWS S3

Como puede leer en este artículo, recientemente tuve algunos problemas con mi servidor de correo electrónico y decidí subcontratar la administración del correo electrónico al Simple Email Service (SES) de Amazon.

El problema con esa solución fue que hice que SES guardara mensajes nuevos en un depósito de S3, y el uso de la Consola de administración de AWS para leer archivos dentro de los depósitos de S3 se vuelve obsoleto muy rápido.

Así que decidí escribir un script Bash para automatizar el proceso de descarga, almacenamiento y visualización de mensajes nuevos.

Si bien escribí este script para usarlo en mi escritorio Ubuntu Linux, no requeriría demasiados retoques para que funcione en un sistema macOS o Windows 10 a través de Windows SubSystem para Linux.

Aquí está el guión completo, todo en una sola pieza. Después de que se tome unos minutos para revisarlo, lo guiaré paso a paso.

#!/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

Comenzaremos con el comando único para descargar cualquier mensaje que resida actualmente en mi bucket de S3 (por cierto, he cambiado los nombres del bucket y otros detalles del sistema de archivos y de autenticación para proteger mi privacidad).

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

Por supuesto, esto solo funcionará si ya ha instalado y configurado la AWS CLI para su sistema local. Ahora es el momento de hacerlo si aún no lo ha hecho.

El comando cp significa "copy", --recursive le dice a la CLI que aplique la operación incluso a varios objetos, s3: // bucket-name apunta a mi depósito (el nombre de su depósito obviamente será diferente), el / home / david ... la línea es la dirección absoluta del sistema de archivos a la que me gustaría copiar los mensajes, y el argumento --profile le dice a la CLI a cuál de mis múltiples cuentas de AWS me refiero.

La siguiente sección establece dos variables que me facilitarán mucho la especificación de las ubicaciones del sistema de archivos a través del resto del script.

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

Observe cómo el valor de la variable tmp_file_location termina con un asterisco. Eso es porque quiero hacer referencia a los archivos dentro de ese directorio, en lugar del directorio en sí.

Crearé un nuevo directorio permanente dentro de la jerarquía ... / emails / para que me sea más fácil encontrar mensajes más adelante. El nombre de este nuevo directorio será la fecha actual.

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

Primero creo una nueva variable de shell llamada hoy que se completará con la salida del comando date + "% m_% d_% Y" . date en sí genera la fecha / marca de tiempo completa, pero lo que sigue ( "% m_% d_% Y" ) edita esa salida a un formato más simple y legible.

Luego pruebo la existencia de un directamente usando ese nombre, lo que indicaría que ya recibí correos electrónicos ese día y, por lo tanto, no es necesario volver a crear el directorio. Si dicho directorio no existe (||), entonces mkdir lo creará por mí. Si no ejecuta esta prueba, su comando podría devolver molestos mensajes de error.

Dado que Amazon SES da nombres desagradables e ilegibles a cada uno de los mensajes que coloca en mi bucket de S3, ahora los renombraré dinámicamente y, al mismo tiempo, los moveré a su nuevo hogar (en el directorio con fecha que acabo de crear) .

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

El bucle for ... do ... done leerá cada uno de los archivos en el directorio representado por la variable $ tmp_file_location y luego lo moverá al directorio que acabo de crear (representado por la variable $ base_location además del valor actual de $ hoy ).

Como parte de la misma operación, le daré su nuevo nombre, la cadena " email " seguida de un número aleatorio generado por el comando rand . Es posible que deba instalar un generador de números aleatorios: será apto para instalar rand en Ubuntu.

Una versión anterior del script creaba nombres diferenciados por números secuenciales más cortos que se incrementaban usando una lógica count = 1 ... count = $ ((count + 1)) dentro del bucle for . Eso funcionó bien siempre que no recibiera más de un lote de mensajes el mismo día. Si lo hiciera, los nuevos mensajes sobrescribirán los archivos más antiguos en el directorio de ese día.

Supongo que es matemáticamente posible que mi comando rand pueda asignar números superpuestos a dos archivos pero, dado que el rango predeterminado que usa rand está entre 1 y 32,576, ese es un riesgo que estoy dispuesto a correr.

En este punto, debería haber archivos en el nuevo directorio con nombres como email3039, email25343, etc. para cada uno de los nuevos mensajes que me enviaron.

Ejecutar el comando de árbol en mi propio sistema me muestra que se guardaron cinco mensajes en mi directorio 02_27_2020 y uno más en 02_28_2020 (estos archivos se generaron usando la versión anterior de mi script, por lo que están numerados secuencialmente).

Actualmente no hay archivos en tmpemails, eso se debe a que el comando mv mueve los archivos a su nueva ubicación, sin dejar nada atrás.

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

La sección final del script abre cada mensaje nuevo en mi editor de texto de escritorio favorito (Gedit). Utiliza un bucle for ... do ... done similar , esta vez leyendo los nombres de cada archivo en el nuevo directorio (al que se hace referencia usando el comando " today ") y luego abriendo el archivo en Gedit. Tenga en cuenta el asterisco que agregué al final de la ubicación del directorio.

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

Todavía queda una cosa más por hacer. Si no limpio mi bucket de S3, descargará todos los mensajes acumulados cada vez que ejecute el script. Eso hará que sea cada vez más difícil de manejar.

Entonces, después de descargar con éxito mis nuevos mensajes, ejecuto este breve script para eliminar todos los archivos en el depósito:

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