What's the best method for retrieving sender/subject from a pop3 acct, via the command line?
I just need to get just the sender's email address and the email subject from a pop3 account, from the command line or a BASH script. I'm running on a MacOS X machines, but want to avo开发者_如何学JAVAid AppleScript. I've looked at getmail_fetch
, but this seems to pull down the entire emails - I was hoping for something more space/time efficient. Is there some obvious trick I'm missing?
Solution using legacy sh.
#!/bin/sh
#
#
STATE=1
USER=myname
PASS=mypass
HOST=mail.example.com
PORT=pop3
MSGFILE=/tmp/msgid
POPFILE=/tmp/popcmds
DONE=/tmp/popdone
doneproc()
{
cat $DONE.tail $DONE.telnet | while read p; do kill -9 $p; done
rm -f $POPFILE $MSGFILE $DONE.tail $DONE.telnet
exit
}
reqmsg()
{
MSGID=`head -1 $MSGFILE`
if [ -z "$MSGID" ]; then echo "QUIT" >>$POPFILE; doneproc; fi
tail -n +2 $MSGFILE > $MSGFILE-
mv $MSGFILE- $MSGFILE
echo "TOP $MSGID" >>$POPFILE
}
rm -f $MSGFILE $DONE.tail $DONE.telnet
> $MSGFILE
> $POPFILE
sh -c "echo \$\$ > $DONE.tail; exec tail -f $POPFILE" | sh -c "echo \$\$ > $DONE.telnet; exec telnet $HOST $PORT" | while read -t 10 f
do
case "$STATE" in
1) case "$f" in
+OK*) echo "USER $USER" >>$POPFILE; STATE=2;;
esac;;
2) case "$f" in
+OK*) echo "PASS $PASS" >>$POPFILE; STATE=3;;
*) echo "Bad response to user command ($f)" >&2; exit 1;;
esac;;
3) case "$f" in
+OK*) echo "LIST" >>$POPFILE; STATE=4;;
*) echo "Bad response to password command ($f)" >&2; exit 1;;
esac;;
4) case "$f" in
+OK*) STATE=5;;
*) echo "Bad response to LIST command ($f)" >&2; exit 1;;
esac;;
5) case "$f" in
.*) reqmsg; STATE=6;;
[0-9]*) msgid=`echo $f | awk '{print $1;}'`
echo $msgid >> $MSGFILE;;
*) echo "Bad response to LIST command ($f)" >&2; exit 1;;
esac;;
6) case "$f" in
+OK*) STATE=7;;
*) echo "Bad response to TOP command ($f)" >&2; exit 1;;
esac;;
7) case "$f" in
.*) echo "---"; reqmsg; STATE=6;;
From:*) echo $f;;
Subject:*) echo $f;;
esac;;
*) echo STATE $STATE and got $f;;
esac
done
Solution using modern bash.
#!/bin/bash
#
#
STATE=1
USER=myname
PASS=mypass
HOST=mail.example.com
PORT=pop3
declare -A MSGIDS
declare -i NUMID
NUMID=0
declare -i CURID
CURID=0
coproc telnet $HOST $PORT
reqmsg()
{
if [ $CURID = $NUMID ]; then echo "QUIT" >&${COPROC[1]}; fi
echo "TOP ${MSGIDS[$CURID]}" >&${COPROC[1]}
((CURID++))
}
while read -t 10 f <&${COPROC[0]}
do
case "$STATE" in
1) case "$f" in
+OK*) echo "USER $USER" >&${COPROC[1]}; STATE=2;;
esac;;
2) case "$f" in
+OK*) echo "PASS $PASS" >&${COPROC[1]}; STATE=3;;
*) echo "Bad response to user command ($f)" >&2; exit 1;;
esac;;
3) case "$f" in
+OK*) echo "LIST" >&${COPROC[1]}; STATE=4;;
*) echo "Bad response to password command ($f)" >&2; exit 1;;
esac;;
4) case "$f" in
+OK*) STATE=5;;
*) echo "Bad response to LIST command ($f)" >&2; exit 1;;
esac;;
5) case "$f" in
.*) reqmsg; STATE=6;;
[0-9]*) read msgid size < <(echo $f)
MSGIDS[$NUMID]=$msgid
((NUMID++));;
*) echo "Bad response to LIST command ($f)" >&2; exit 1;;
esac;;
6) case "$f" in
+OK*) STATE=7;;
*) echo "Bad response to TOP command ($f)" >&2; exit 1;;
esac;;
7) case "$f" in
.*) echo "---"; reqmsg; STATE=6;;
From:*) echo $f;;
Subject:*) echo $f;;
esac;;
*) echo STATE $STATE and got $f;;
esac
done
I just tested these scripts on Linux Mint Quiana and also Scientific Linux, both still work fine with a slight tweak. As in the earlier comment TOP on my server appears to need 2 arguments but as you are only looking at the mail headers just add a space and 0 to the end of the TOP command (0 lists only the mail headers) ie
(first script)
echo "TOP $MSGID 0" >>$POPFILE
or (second script)
echo "TOP ${MSGIDS[$CURID]} 0" >&${COPROC[1]}
I also needed to change "read -t 10 f" to "read -t 50 f" as my POP3 server seems quite slow.
Scientific Linux was happy with the invocation of the "sh" shell however Mint needed the references to "sh" changed to "bash" then all was well
Finally to avoid leaving your POP3 password lying around in a script file it would be better to prompt for it on running the script:
ie
echo "enter password for this POP3 email connecton"
read password
PASS=$password
精彩评论