I’ve known for donkeys’ ages that many Unix shells honour $MAIL: they check the modification time of the file every $MAILCHECK seconds (default: 600) and announce “You have mail”. Back in the days, we then used mail(1) or mailx(1) to read our messages, today it’s more likely mutt(1) or alpine(1).

Tim's original tweet

What I wasn’t aware of, and I thank Tim (of @ed1conf fame) for showing me, is that POSIX shells should honour $MAILPATH, a colon-separated list of file names, for the shell to check for incoming mail.

More importantly, $MAILPATH can contain optional notification messages for each mailbox, and these are separated by ? from the filename (in Bash) or, as POSIX mandates, by a % which Bash also supports. The notification message itself is expanded by the shell.

$ MAILCHECK=1
$ MAILPATH=/var/mail/jpm%'Mail for $USER at $(date)':$HOME/logg%'$(tail -1 $HOME/logg)'
$ echo hello | mail jpm
$ pwd
/home/jpm
Mail for jpm at Fri Mar  6 16:49:56 UTC 2020
$ echo "Dinner time" >> logg
Dinner time
$

These two variables would cause a compliant shell to check for mail to me every second, and to check whether the file $HOME/logg has been modified, and if so, print its last line.

Quoting Tim and POSIX:

POSIX requires parameter expansion in MAILPATH: “Each pathname can be followed by ‘%’ and a string that shall be subjected to parameter expansion and written to standard error when the modification time changes” which includes “Command Substitution”

I’m thinking of interesting things we could do with this – think $MAILCHECK set to 0 which means the shell shall check before issuing each primary prompt ($PS1).

We’ve been playing around with this for a bit, and to cut a long story short: verify that this works in the shell you use.

And last but not least: Tim is a person you should follow if you’re interested in Unix commands and odds and ends; he digs up the neatest things.

unix, mail, and shell :: 06 Mar 2020 :: e-mail