Enviando un mail de gmail desde la línea de comandos

Enviar mails desde la línea de comandos de Linux es bastante sencillo. Hay un comando llamado «mail» que hace esto sin problemas. Si nos instalamos un servidor de correo SMTP como postfix, ya lo tendremos.

El problema es que estaremos enviando mails desde un servidor de correo cuyo dominio (el que hayamos puesto nosotros, algo como «micasa.com») o bien no existe o si lo hace no está a nuestro nombre. Si enviáis unos pocos e-mails al día puede que todo vaya bien pero, si enviáis más correos, esto puede ocasionar problemas (por ejemplo, vuestro proveedor de servicio a Internet os pegaría un toque por posible SPAM).

Lo mejor es hacer las cosas bien hechas para evitar problemas (*); en este caso, lo suyo es enviar correos legítimos, desde una cuenta «oficial», de un dominio «oficial» (registrado, vamos). Vamos, que si enviamos un correo desde loquesea@gmail.com, ese correo debería partir del servidor gmail.com, es decir, el servidor de correo de Google.

Para hacer esto desde línea de comandos os recomiendo el comando «mailx», que además nos permite enviar adjuntos.

Vamos a ver cómo usarlo para enviar un mail desde nuestra cuenta de gmail. Lo que vamos a ver es cómo usar mailx para enviar correos desde la línea de comandos usando nuestra cuenta de gmail (a través, por supuesto, de los servidores de Google).

Lo que tenemos que hacer es especificar los distintos parámetros (servidor, puerto, usuario, password…) con la opción -S. Nos quedaría algo así:

mailx -v -s "ASUNTO" -S smtp=smtp.gmail.com:587 -S smtp-auth-user=VUESTRO_USUARIO_DE_GOOGLE@gmail.com -S smtp-use-starttls -S smtp-auth-password=VUESTRO_PASSWORD -S from=VUESTRO_USUARIO_DE_GOOGLE@gmail.com MAIL_DESTINO

Al ejecutar esto os dejará escribir el cuerpo del mensaje. Para finalizar el mail, dar un par de veces a Intro, escribid un punto y darle de nuevo a Intro (es la forma de decirle a mailx que habéis terminado de redactar el mail).

Si queréis hacerlo menos interactivo podéis pasarle el cuerpo del mensaje así:

echo «CUERPO DEL MENSAJE…» | mailx -v -s «ASUNTO»…

Si queréis un cuerpo más completo, con intros y demás, podéis pasarle un archivo (tanto como cuerpo de mensaje como de asunto). También podéis registrar los logs de salida y error por si algo fallara poder estudiar cuál ha sido el problema. Un script que contemple ambas cosas podría quedar así:

DATE=`date +%Y-%m-%d--%H-%M`
if [ $# = '0' ]; then
     echo send_gmail FILE_SUBJECT FILE_BODY \[ FILE_ATTACH \]
elif [ $# > '1' ]; then
     SUBJECT=`cat $1`
     if [ $2 ]; then
        BODY=`cat $2`
     else
        BODY="."
     fi
     ATTACH=$3
     if [ $ATTACH ]; then
        echo $BODY | mailx -v -s $SUBJECT -a $ATTACH -S smtp=smtp.gmail.com:587 -S smtp-auth-user=VUESTRO_USUARIO_DE_GOOGLE@gmail.com -S smtp-use-starttls -S smtp-auth-password=VUESTRO_PASSWORD -S from=VUESTRO_USUARIO_DE_GOOGLE@gmail.com MAIL_DESTINO >/tmp/mail_$DATE.log 2>/tmp/mail_$DATE.err
     else
        echo $BODY | mailx -v -s $SUBJECT -S smtp=smtp.gmail.com:587 -S smtp-auth-user=VUESTRO_USUARIO_DE_GOOGLE@gmail.com -S smtp-use-starttls -S smtp-auth-password=VUESTRO_PASSWORD -S from=VUESTRO_USUARIO_DE_GOOGLE@gmail.com MAIL_DESTINO >/tmp/mail_$DATE.log 2>/tmp/mail_$DATE.err
     fi
fi

Lo he hecho rápidamente, así que se puede mejorar mucho a la hora de tratar los parámetros. De todas formas, así es perfectamente válido (doy fe ;-). A continuación explico cómo funciona.

Lo que hace el script es coger la fecha del sistema (en la variable DATE) para que nuestros archivos de log la tengan incorporada en el nombre de archivo (así es más fácil identificar de cuándo son).

Después, si el número de parámetros es 0 muestro un mensaje de uso correcto del script (cuyo nombre es «send_gmail» en este ejemplo), que básicamente es, el nombre del script, el fichero que lleva el subject del mensaje, el fichero que lleva el cuerpo del mensaje y, opcionalmente, el archivo que queremos adjuntar.

Si el número de parámetros es mayor que 1 (**) el asunto del mensaje (SUBJECT) es el contenido del primer argumento. Si existe un segundo parámetro sería el fichero que contendría el cuerpo del mensaje. Si no existe segundo parámetro se pone un «.» (podemos poner un espacio o una palabra por defecto) porque si no ponemos nada fallará el script.

Si hay un tercer argumento ejecutaremos el comando que hemos visto antes con la opción «-a $ATTACH», que incluirá dicho archivo como adjunto.

Esto os puede venir de perlas para cosas como enviar mails al iniciar el equipo para indicar que está operativo (como vimos en el artículo anterior «Ejecutar scripts al inicio de Linux»), para enviar mails de notificación desde nagios o, como veremos en un artículo posterior, para hacer backups de archivos rápida y cómodamente.

(*) Esto se debería aplicar a todos los aspectos de la vida. Si todo el mundo lo hiciera… irían mejor las cosas, nor?
(**) como mínimo hemos introducido subject y body; si introducimos 3, el tercero es el fichero a adjuntar; a partir del tercer parámetro se ignoran si los hubiera.