Because MH utilities are individual programs -- instead of a monolithic mail program like mail(1)-- you can run "batch" processes to manipulate your messages for you. Most UNIX systems have either or both of the programs at(1) and cron(8). These utilities execute other programs at the times and dates you choose.
For example, rmm doesn't remove messages; it renames them and leaves the "deleted" files in your mail folder. The .xmhcache files that xmh and exmh leave in folders can take a lot of disk space; you might want to remove those files from folders that haven't been used in a long time. Maybe you want to run a script like autoinc in the middle of the night, when the system isn't busy but you also aren't logged in. Periodically-run programs can do those things and many others. This section introduces the techniques and gives some examples.
There's a risk in running a non-interactive program when you aren't there to supervise. If something goes wrong, the program could cause serious trouble in your mail folders -- and in non-mail directories, too. If you don't have experience with at(1) and cron(8), be careful! Start by running programs that don't remove or modify files.
Even if your job doesn't remove or modify anything, there's another problem. A "background" job can change your current folder or message if it isn't designed to avoid that. That can cause real confusion if you're using an interactive MH session or if you leave MH and come back later -- if you don't realize that the background job may have changed your current folder, message, or the contents of a sequence. The Section Multiple MH Sessions has tips.
It's a good idea to test your setup on a "dummy" account that no one uses. Or, at least, make a separate MH directory and run your jobs there. See the Section A Test Mail Setup.
One other problem that might affect you: If your shell reads a setup file whenever a new shell starts, and that setup file can affect your cron or at job. That's because cron and at start a shell to read the command lines you give them. For example, C shell users' .cshrc files will be read. But C shell .login files and Bourne shell .profile files won't be read because those files are only read when a login shell starts. For more information, check a good book on UNIX shells. (The chapter of UNIX Power Tools about setup files shows ways to customize which parts of the startup files are read by at and cron jobs -- and to work around bugs.)
53 0 * * * /bin/sh $HOME/.lib/at_cron/deltempfiles # mhmail WON'T SEND AN EMPTY MESSAGE; GREAT WHEN calendar SAYS NOTHING: 6 6 * * 1-5 /bin/calendar | /usr/local/mh/mhmail $USER -s "calendar Output"In general, it's a good idea to use absolute pathnames (starting with a slash, /) unless you know where they aren't needed. The shell's command search path may not have all the directories (like your personal bin) that you're accustomed to using in a login shell. The current directory for personal crontabs is usually the home directory, but that isn't always true.
The first five fields on a line, separated by spaces, are:
minutes hours day-of-month month day-of-week
Each of those can be a list (like 3,6,9) or a range (like 1-5). An asterisk (*) in a field matches all values. A hash mark (#) in the first column starts a comment.
So, in the example crontab above, the first line runs my deltempfiles script with the Bourne shell every day at 0053 hours (12:53 am). The /bin/sh isn't needed on systems that can execute scripts directly (Section How Does Your System Execute Files? tells how to find out if yours does). The second line is a comment. The third line runs at 6:06 a.m. every weekday morning (Monday is "day 1" on my system's cron).
To make entries in your crontab, there may be a command named crontab(1). Note that many crontab(1) programs are perfectly happy to delete your entire crontab file without confirmation; it's a good idea to save a backup copy of complex files.
The basic operation of at is simple. On its command line, give the time and an optional date when you want the job to run. (If you don't give the date, the job will run at the next scheduled time, in the next 24 hours.) Then at reads a list of command lines to run from its standard input. So, if you have a file named atjob that looks like this:
/bin/sh $HOME/.lib/at_cron/deltempfiles echo "Deleted temp files from at -- check folders" | /usr/ucb/mail ehuserYou can submit it to run at 1:35 a.m. tonight with the following command:
% at 0135 < atjob(The < is the shell's operator that redirects standard input to come from a file.) That job will run just once. If you want it to run every night, have at resubmit the job. To do that, add sleep and at commands to the end of the file. For example, to run atjob at 1:35 every night, make the file:
/bin/sh $HOME/.lib/at_cron/deltempfiles echo "Deleted temp files from at -- check folders" | /usr/ucb/mail ehuser sleep 60 /usr/bin/at 0135 < atjobThe sleep 60 command waits 60 seconds to be sure that the job won't be submitted again at the same minute today; this guarantees that the job won't run twice in the same day. at runs jobs from the same current directory where you submitted the job, so < atjob doesn't need an absolute pathname.
If your system doesn't show you the errors and output you want to see, redirect the output of jobs to a file or a mail message.
#!/bin/sh PATH=/usr/local/mh:$PATH MHCONTEXT= export PATH MHCONTEXT scan +drafts 2>/dev/null | mhmail youraddress -subj "Old drafts in +drafts"The Bourne shell operator 2>/dev/null throws away errors like "no messages in +drafts" so they won't be mailed. mhmail doesn't send a message if there's no text on its standard input.
#!/bin/sh cd /u/ehuser/Mail || exit find `find . -type d -name DELETE -print` -type f -mtime +4 -exec rm -f {} \:Here's the xargs version:
#!/bin/sh cd /u/ehuser/Mail || exit find `find . -type d -name DELETE -print` -type f -mtime +4 -print | xargs rm -fThe first line changes to your MH Mail directory and (important!) exits if the cd command fails. Otherwise, your find job could start deleting in some other directory. The second line runs two find jobs: one to find the DELETE folders, and one to find messages in those folders that have been there for four days. (If you have experience with the standard UNIX find(1), you might be wondering why I had to use the nested finds. It's because predicates like -name 'DELETE/[1-9]*' don't work.)
I used `find -type d ...` to get a list of folders, instead of using `folders -fast -recurse`, because there might be some other users' folders or read-only folders in the output of the folder command.
#!/bin/sh MHCONTEXT=/tmp/clean$$ export MHCONTEXT /usr/local/mh/rmm `/usr/local/mh/pick -before -7 -list +msgs` rm -f /tmp/clean$$
[Table of Contents] [Index] [Previous: Draft Message Template Files] [Next: Automatic Signature on End of Messages]
This file is from the third edition of the book MH & xmh: Email for Users & Programmers, ISBN 1-56592-093-7, by Jerry Peek. Copyright © 1991, 1992, 1995 by O'Reilly & Associates, Inc. This file is freely-available; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation. For more information, see the file copying.htm.
Suggestions are welcome: Jerry Peek <jpeek@jpeek.com>