Check Gmail From the Command Line

Gmail provides the ability to view your new/unread email as an ATOM feed via https://mail.google.com/mail/feed/atom.  With cURL and some Perl we can check gmail from the Linux command line.

Just change the email address to your email address and when your hit enter you will be prompted for your gmail password.

#!/bin/bash
curl -u motersho@gmail.com --silent "https://mail.google.com/mail/feed/atom" |
 perl -ne \
  '
    print "SUBJECT: $1 \n" if /<title>(.+?)<\/title>/;
    print "RECEIVED $1 \n" if /<issued>(.+?)<\/issued>/;
    print "FROM: $1 " if /<name>(.+?)<\/name>/;
    print "($1)\n\n" if /<email>(.+?)<\/email>/;
  '

HOWTO: Send SMTP commands via a bash script and the /dev/tcp device file

Scroll down to script

Today at work, the support staff needed to check and see if a customer’s email server was setup to relay mail via their database server.  Normally when asked, I direct the support staff to the send the SMTP commands via Telnet like so:

You do/type this Server responds with
Telnet to hostname on port 25 220 (then identifies itself – possibly with several lines of 220 + text)
HELO your_domain_name or whatever 250 (followed by human readable message)
MAIL FROM:you@hostname.com (ie, your email address) 250 is syntactically correct (or similar)
RCPT TO:them@someplace_else.com (email address you want to send to) 250 is syntactically correct
DATA Tells you to send data then CRLF period CRLF at end
You type your message then CRLF period CRLF (ie, type a period on a line by itself then hit ENTER) 250
QUIT Signoff message

But I figured instead of telling them the same thing every other week it was time to brush up on my bash scripting skills and learn something new in the process.

I first tried to read in the variables and then send them out to a telnet command but quickly realized that once telnet was executed in the script it would no longer accept the bash variables that I had created.  I knew from previous scripts that I could use the expect commands (more info) but expect is not usually a package that gets installed on a linux server by default and most of these servers are production database servers, which no admin would allow a random package to get installed with out testing it first.

So with expect out of the question it was time for some Google searches which let me to an article from the Linux Journal titled “More on Using Bash’s Built in /dev/tcp File (TCP/IP)“  This struck my interest, first because I didn’t know that this was possible and second because this was the same way that I had done it in the Windows/AutoIT world (I will post more about this later).  Here is the full script that I wrote.  Feel free to use this as you need or if you see a way for me to make it better please let me know.
Script

#!/bin/bash
 
# Written by: Terry Moore
# Created on Date: 2009-10-12
# Test mail relay from a Linux database server 
# Version 0.2 
# Last update 2009-10-13
 
#Body of Email
DATA="The test message has been sent"
 
#Subject of Email
SUBJECT="Mail Relay Test"
 
 
######### Header ##########
echo
echo
echo
echo "***************************************"
echo "*                                                           *"
echo "*             Mail Relay Test App                    *"
echo "*                                                           *"
echo "***************************************"
echo 
echo "Press control+c at any time to cancel"
echo "Please answer all of the following questions:"
echo
 
 
##### Get Mail Server #######
LOOP=0
while [ $LOOP -ne 1  ]
do
	echo -n "Enter Mail Server Name: " ; read MAILSERVER;
	if [ "$MAILSERVER" != '' ] ; then
		LOOP=1
	fi
done
 
 
###### GET PORT ##########
echo -n "Enter Port: [typically 25]: "; read PORT;
if [ "$PORT" = '' ] ; then
	LOOP=1
	PORT="25"
fi
 
###### GET MAIL FROM ##########
echo -n "Enter Mail From: [support@email.com]" ; read MAILFROM
if [ "$MAILFROM" = '' ] ; then
	MAILFROM="support@email.com"
	LOOP=0
fi
 
###### GET MAIL TO ##########
LOOP=0
while [ $LOOP -ne 1 ]
do
	echo -n "Enter Mail To: " ; read MAILTO
	if [ "$MAILTO" != '' ] ; then
		LOOP=1
	fi
done
 
 
#### SEND MAIL via RAW TCP #######
echo 
echo "Connecting to $MAILSERVER on Port $PORT";
echo "Please wait ... "
echo
exec 3<>/dev/tcp/$MAILSERVER/$PORT 
 
if [ $? -ne 0 ] ; then
	echo
	echo "ERROR: Cannot connect to the Mail Server";
	echo "Please check the servername and/or the port number"
	exit
fi
 
echo -en "HELO mail.email.com\r\n"  >&3 
echo -en "MAIL FROM:$MAILFROM\r\n" >&3
echo -en "RCPT TO:$MAILTO\r\n" >&3
echo -en "DATA\r\n" >&3
echo -en "Subject: $SUBJECT\r\n\r\n" >&3
echo -en "$DATA\r\n" >&3
echo -en ".\r\n" >&3
echo -en "QUIT\r\n" >&3
cat <&3
 
 
echo
echo
echo "Check the above output for errors"
echo

I know I have to do more error checking and data sanitizing but you can get the drift as to how to use bash’s builtin /dev/tcp device file to send telnet commands.

More on Using Bash’s Built-in /dev/tcp File (TCP/IP)