MH & nmh: Email for Users & Programmers

May, 2006

Folders

If you don't send or receive many mail messages, you may not need to know about MH folders. But if you get a lot of mail, or if you want to organize messages into groups (like folders in a file cabinet), read on.

By default, MH keeps all your messages in a single folder called inbox. Each message in the folder has a unique message number. You can make other folders and move one or more messages into them.

Your Current Folder: folder

First, here's how to get a summary of your current folder. That's the folder MH uses until you tell it to change folders. Until now, your current folder has probably been inbox, the folder where new mail is put. To get the summary of your current folder, use the folder command:

    % folder
         inbox+ has  46 messages (   1-  46); cur=  17.
    
If you want a heading that explains each part, add -header:
    % folder -header
         Folder     # of messages (  range  ); cur  msg  (other files)
         inbox+ has  46 messages  (  1-   46); cur=  17.
    
The two commands above show that: To get more information, use the scan command. It shows a listing of messages in the current folder, one line per message:
    % scan
       1  01/09 Joe Doe            Test message<<Hi!>>
            ...
      17+ 01/11 To:Joe Doe         Re: Something that you should know
            ...
      46  01/13 someone@somewhere. Did we meet at USENIX?<<I think th
    %
    
If there are lots of messages to scan, they can scroll off the screen faster than you can read them. Because MH runs from the shell, it's easy to use a pipe and UNIX paging commands like more or pg which let you see one screen at a time:
    % scan | more
    
Or, if you don't really need to see all of your messages, you can scan a range of messages:
    % scan last:20
    
The Section Find and Specify with scan, pick, Ranges, Sequences shows other choices.

Using the folder Command to Create and Change Folders

The folder command can also make new folders. To make one named test, type:

    % folder +test
    Create folder "/yourMHdir/test"? y
                      test+ has   no messages.
    
After that, you wouldn't be in the inbox folder anymore. Your current folder would be test. You haven't put any messages there yet, so the folder is empty. For example:
    % scan
    scan: no messages in test
    
Your current folder will be test until you change it to something else or until you incorporate new mail (inc changes your current folder to inbox).

To change your current folder back to inbox, type:

    % folder +inbox
               inbox+ has  46 messages  (   1-  46); cur=  17.
    

Changing to Another Folder

The Section above showed that the folder command can change your current folder. But you don't have to use folder. When you give a folder name to most MH commands, they change the current folder. For instance, show +junk changes the current folder to junk and shows the current message there.

Two MH commands accept folder name arguments but don't change the current folder:

That is, the following command moves messages 45 and 47 to the junk folder, but it doesn't change the current folder:
    % refile +junk 45 47
    
The relative folder operator @ can be used to change folders, too.
CAUTION: If you ask an MH command to change the current folder and the command doesn't work for some reason, the current folder won't be changed. For example, the following scan command fails because there are no messages in the bar folder (the folder is empty). As you can tell from the second folder command, the current folder wasn't changed:
      % folder
                     foo+ has   5 messages (   7-  22); cur=  9.
      % scan +bar
      scan: no messages in bar
      % folder
                     foo+ has   5 messages (   7-  22); cur=  9.
      
If you've just tried to change the current folder and you get a warning or error -- you might use folder to check the current folder before using a command like rmm that's hard to undo.

Plus signs can be confusing when you start with MH. If you're a little confused, the sidebar The Pluses of MH might help.

Moving and Linking Messages: refile

The refile command moves or links messages between folders. By default, the message is moved out of one folder into another folder. The -link switch leaves the message where it is and makes a UNIX link ("hard," not symbolic) into another folder.

Moving

To move messages out of your current folder into another folder, use refile +foldername, where foldername is the destination folder. refile doesn't change the current folder (unless you use its -src switch). If you don't give message number(s), refile defaults to the current message.

Here's an example. Find a message you want to refile by using scan and show. Then, move it to the test folder. To be sure it's gone, scan the same messages or try to show the current message:

    % scan 1-4
       1  01/09 Joe Doe            Test message<<Hi!>>
       2  01/09 Joe Doe            Another test<<Well, this is another
       3+ 01/09 To:angelac         A message from MH mail<<Did this wo
       4  01/09 To:Joe Doe         What's happening -- did you send the
    % show
    (Message inbox:3)
    To: angelac
        ...
    % refile +test
    % scan 1-4
       1  01/09 Joe Doe            Test message<<Hi!>>
       2  01/09 Joe Doe            Another test<<Well, this is another
       4  01/09 To:Joe Doe         What's happening -- did you send the
    % show
    show: no cur message
    
You refiled the current message into test. So the second scan and show tell you that there's no current message.

Did the message really get to the test folder? Here's a shortcut to find out. You can change the current folder and scan it by giving a folder name to the scan command as shown in the following example:

    % scan +test
       1  01/09 To:angelac         A message from MH mail<<Did this
    % folder
                test+ has   1 message  (   1-   1).
    
Notice that:

If you want to keep the same message number, you can use refile -preserve..., but this only works if there's not a message with that number in the destination folder. Here's an example of trying to move message 1 (the current message) from inbox to test and preserve the message number. There's already a message 1 in test, so refile complains and won't move the message:

    % folder
              inbox+ has  45 messages (   1-  45); cur=  1.
    % refile -preserve +test
    refile: message xxx/test/1 already exists
    
You should know that refile doesn't actually "move" a message to another folder in one step. Instead, refile first makes a hard link, if possible--otherwise, it makes a copy. Then it renames the source message file to start with a comma (,) or hash (#), which "hides" the message from MH; the renamed file stays in the source folder to be actually removed later. The rmm command "removes" messages in the same way, by default; see the Section How rmm Removes Messages for details.

In nmh-1.0 and above, you can tell refile to actually remove the source message with the -unlink switch. So, for example, refile -unlink 23 +foo will move message 23 to the foo folder and completely remove it from the current folder.

CAUTION: The nmh-1.0 version of refile will effectively ignore the -unlink switch if you have an rmmproc defined in your MH profile. If you have an rmmproc, you must use refile -unlink -normmproc to have the source message unlinked.

nmh and later versions of MH also have two switches that control the rmmproc.

To choose your own rmmproc from the command line, use the switch -rmmproc progname, where progname is the program that will "remove" the message file. This rmmproc overrides any rmmproc: MH profile entry. So, if you want to use different rmmprocs for rmm and refile, add entries like these two to your MH profile:

    rmmproc: rmmproc-for-rmm
    refile: -rmmproc rmmproc-for-refile
    
(In both the MH profile and on the command line, progname must be a single program name, with no options or arguments of its own. If you need to add arguments, make a small shell script that calls the program; list that shell script as the rmmproc.)

Newer MHs and nmh have a -normmproc switch. This tells refile to ignore any rmmproc: MH profile entry and instead use the default renaming method to "remove" the source message files.

Linking Messages into More than One Folder

Let's say that you want to store a message in more than one folder. You might do this if you had a folder for each project you were working on and if one message had information about two different projects. You would do this by linking rather than moving the message. When a message is linked to another folder or folders, you can find it in the folder where it started and also in the other folders. On UNIX, linking a message into multiple folders takes much less disk space than copying the message into those same folders. (Each link needs a few bytes for its new directory entry; that's all.) One gotcha: as the Section Links explains, the hard links MH uses can't cross filesystems (there's a workaround in the Section Using Symbolic Links).

For example, let's link our message from test into another folder named junk. Then, compare the test and junk folders:

    % refile -link +junk 1
    Create folder "/yourMHdir/junk"? y
    % folder
                test+ has   1 message  (   1-   1); cur=  1.
    % scan
       1+ 01/09 To:angelac         A message from MH mail<<Did this wo
    % scan +junk
       1  01/09 To:angelac         A message from MH mail<<Did this wo
    
If you want to refile a message into two or more folders, you can do it all in one step -- just type all the folder names at once. This works whether you're moving or linking. Let's try it. Scan the first four messages in your inbox. You can use the folder name and message numbers together, like this:
    % scan +inbox first:4
       1  01/09 Joe Doe            Test message<<Hi!>>
       2  01/09 Joe Doe            Another test<<Well, this is anothe
       4  01/09 To:Joe Doe         What's happening -- did you send t
       5  01/09 To:Joe Doe         Thanks for helping!<<You said that
    
To link message 1 from inbox into both the junk and test folders, use:
    % refile -link +test +junk 1
    
Now the message should be linked into all three folders. (Check it if you want to.) The Figure below shows what this might look like if MH stored messages on paper instead of a computer disk.

Figure: Message linked into three folders

meliithf.jpg

If you hadn't used its -link switch, refile would have linked the message into junk and test but removed it from the current folder (inbox).

A handy way to use links is a single folder with links to many other folders. The Section Using Links explains more about links.

Refiling from Another Folder with refile -src

As you've seen above, refile moves or links messages from the current folder. You can tell refile to take messages from a different folder by using its -src switch and a folder name. For example, to move messages 1, 3, and 5 from the project folder into the done folder, you could do it in one step this way:

    % refile 1 3 5 -src +project +done
    
The same thing done in two steps would look like this:
    % folder +project
            project+ has  23 messages (   1-  47); cur=  1.
    % refile 1 3 5 +done
    
Either way you do it, after refile finishes, your current folder will be project. Unlike plain refile, the refile -src switch changes the current folder.

Subfolders

Okay, so you're one of those people with thousands of mail messages, and you need to subdivide your folders? MH lets you do that; you can make subfolders -- folders inside your folders. (In case you're wondering, you can make sub-subfolders and sub-sub-subfolders and.... I've made folders ten levels deep to see how it works. It does.)

The Figure below shows a folder that has four messages and a subfolder in it. The subfolder has three messages in it.

To name a subfolder, type the top-level folder name, a slash (/), and the subfolder name -- with no space between them. For example, if you have a folder named reports and want a subfolder called jan, the complete subfolder name would be reports/jan. (Remember that in UNIX uppercase and lowercase letters are distinct. A subfolder named reports/Jan is different than a subfolder named reports/jan. Using all lowercase letters may be easier to type and less confusing in the long run; that choice is up to you.)

Figure: A subfolder

asubfold.jpg

The MH 6.7 and later versions of folder will make the top-level folder and its subfolder(s) for you. Just type the command:

    % folder +reports/jan
    Create folder "/yourMHdir/reports/jan"? y
               reports/jan+ has   no messages.
    
To create a subfolder in MH 6.6 and previous versions, you first have to create the folder levels above it. For example, if you want a folder named reports/jan, you have to make the reports folder first with folder +reports; then use folder +reports/jan.

To move (or link) messages into a subfolder, use the name with a plus sign (+) before it. (You can also use the relative-folder operator @ (at sign). In the next example, we'll move message 6 from inbox into the reports/feb subfolder (in this case, reports/feb doesn't exist yet, so refile asks if you want to create it):

    % show 6 +inbox
    (Message inbox:6)
        ...
    % refile +reports/feb
    Create folder "/yourMHdir/reports/feb"? y
    
You can tell if a folder has subfolders by looking at the output of the folder command. For instance, by now the reports folder has two subfolders:
    % folder +reports
                reports+ has   no messages            ;    (others).
    
The (others) at the end means "there's something besides messages in the folder." Those could be subfolders or non-MH files. An easier way to tell what's there is to ask folder for a "recursive" listing; that is, the folder and all the subfolders. That's what folder -recurse is for, as shown below:
    % folder -recurse
           reports+ has   no messages          ;           (others).
       reports/jan  has    1 message  (  1-  1).
       reports/feb  has    1 message  (  1-  1).
    
Your current folder is reports; it has two subfolders named for two months.

A nice way to get a summary of your current folder and its subfolders is:

    % folders @.
            Folder      # of messages ( range ); cur msg  (other files)
           reports+ has   no messages          ;          (others).
       reports/feb  has    1 message  (  1-  1).
       reports/jan  has    1 message  (  1-  1).

                 TOTAL=    2 messages in 3 folders.
    
The @. means "the current folder"; see the next section.

Relative Folder Names

As you've seen, a complete (full) subfolder name always starts with the top-level folder name. Typing all of the name can be a waste of keystrokes, especially when you're already in the top-level folder. For instance, let's say that you have a lot of letters from friends in a folder named friends. If you decide to reorganize the mail into subfolders named for each friend, typing the complete subfolder name can get to be a pain:

    % folder +friends
          friends+ has 124 messages (  12- 198); cur= 19.
    % scan 12
      12  02/15 To: zebra!ellen    What Joseph and Annie are doing
    % refile 12 +friends/Joseph +friends/Annie
    Create folder "/yourMHdir/friends/Joseph"? y
    Create folder "/yourMHdir/friends/Annie"? y
    % scan next
      14  02/15 "Ellen K. Grimm"   Re: What Joseph and Annie are d
    % refile 14 +friends/Joseph +friends/Annie
    
If you're using a shell that has the curly-brace string operators ({ }), like the C shell or bash, they'll let you type only the parts of the folder names that are different. For example, on those shells, you could have typed the previous command as:
    % refile 14 +friends/{Joseph,Annie}
    
The shell will expand +friends/{Joseph,Annie} into +friends/Joseph +friends/Annie.

Here's an even easier way, though, for this case. Because you're already in the friends folder (your current folder), you don't have to type its name. You can do this with relative folder names. To say "the subfolder called xxx in my current folder," you use an at sign (@) instead of a plus sign (+). If your current folder is friends, you can refer to the subfolder Joseph by typing @Joseph. Let's go on with the example above, but use relative folder names this time:

    % folder
             friends+ has 122 messages (  15- 198).
    % scan 15
      15  02/16 To: zebra!ellen    Joseph Annie & Carl(!)<<Guess w
    % refile 15 @Joseph @Annie @Carl_B
    Create folder "/yourMHdir/friends/Carl_B"? y
    % scan next
      17  02/16 "Ellen K. Grimm"   Re: Joseph Annie & Carl(!)<<I d
    
Compare the two examples. Think how much more typing you'd need without the short folder names....
NOTE: Remember, these relative folder names work only for subfolders of your current folder. If you're in the reports folder and you type @Annie, MH will think you mean the folder named reports/Annie (not the folder named friends/Annie). In this case, you want to use a plus sign (+) and the complete folder name: +friends/Annie.
You can use relative folder names almost anyplace, not just with refile. (For some reason, many versions of rmm don't accept relative folder names. The rmm with MH 6.8.3 does.) For example, here's how to change your current folder from friends to friends/Joseph and scan it:
    % scan @Joseph
       1  02/15 To: zebra!ellen    What Joseph and Annie are doing
       2  02/15 "Ellen K. Grimm"   Re: What Joseph and Annie are d
       3  02/16 To: zebra!ellen    Joseph Annie & Carl(!)<<Guess w
    % folder
      friends/Joseph+ has   3 messages (   1-   3).
    
The next obvious question is: how can you get back to the folder above (called the parent folder)? There are two ways:
  1. Type the complete folder name (+friends).
  2. Type the relative folder name (@.. -- that's an at sign with two dots after it).
If you've ever used .. in the UNIX filesystem (for example, cd ..), you'll see that this @.. in MH works the same way. Continuing the example above, from the friends/Joseph folder:
    % folder @../Ellen
       friends/Ellen+ has   2 messages (   1-   2).
    % folder @..
             friends+ has 121 messages (  17- 198).
    
Because you were in the friends/Joseph folder, typing folder @.. took you to the parent folder, friends. If this relative-name business seems too confusing, you don't have to use it. But if you do a lot of work with subfolders, relative folder names can save you a lot of typing.

folder -fast

As you've seen, if you don't give the folder command any switches, it will summarize the folder's contents. This can take time on busy computers.

If you just want the current folder name without the summary, you can use the -fast switch, as shown in the following example:

    % folder -fast
    friends
    
The -fast switch won't save much time when you use folder -recurse. Although it won't print folder summaries, it still has to search every folder for subfolders, and that takes more time.
    % folder -fast -recurse
    friends
    friends/Annie
    friends/Carl_B
    friends/Joseph
    
As with other MH commands, you can abbreviate the switch names. Type just enough letters to make the name unambiguous. For instance, you can shorten folder -fast -recurse to folder -f -r. A quick way to see all the switches so that you can figure out the shortest unique abbreviation is with the folder -help command.

To change your current folder quickly, nothing beats folder -f. For example, folder -f +inbox makes inbox current, without the folder summary. It just changes the folder and shows the name.

CAUTION: In early versions of MH, folder -fast +foldername would not change your current folder to foldername! Back then, the folder -fast command was just for showing the name of the current folder, not for changing folders. When you typed folder -fast +newfolder, the folder command would answer newfolder as if it had changed the current folder -- but it hadn't.

If you're not sure what your MH version does, try to change to another folder with folder -fast +foldername. Then check the current folder name by typing folder. If the current folder isn't foldername, you're probably running an old version of MH.

List of All Folders: The folders Command

The folder command gives a summary of one of your folders. For a summary of all your top-level folders, use the command folders (plural) or folder -all. If you have subfolders, you can add -recurse. All of these commands put a heading before the folder list and a summary at the end. Finally, if you just want the total number of messages and folders, use folders -total, with or without the -recurse. It's time for an example (and remember -- you can abbreviate most switches):

    % folders -recurse
              Folder      # of messages (  range  ); cur  msg  (other files)
               inbox  has   45 messages (   1-  45); cur=  1.
             friends+ has  121 messages (  17- 198);           (others).
       friends/Annie  has    3 messages (   1-   3).
      friends/Carl_B  has    1 message  (   1-   1).
      friends/Joseph  has    3 messages (   1-   3).
             reports  has   no messages            ;           (others).
         reports/jan  has    2 messages (   1-   2); cur=  2.
         reports/feb  has    1 message  (   1-   1).

                  TOTAL=  176 messages in 8 folders.
    % folders -total
    TOTAL=  166 messages in 3 folders.
    % folders -t -r
    TOTAL=  176 messages in 8 folders.
    
NOTE: Using -recurse can slow down folders quite a bit. Don't use -recurse unless you want to see your subfolders.

The fols shell script gives you a list of folder names in columns, with long names shortened.

List Folders in Columns with fols

fols, a program in this book's online archive, prints the folders -fast output in columns. Like folder, the fols script also has a -recurse option for listing subfolders. fols uses two sed expressions to do the following:

Here's an example with nine folders listed. The current folder is inbox, and the mh-users_tosave/DELETE folder name has been shortened:
    % fols -r
    drafts             drafts/DELETE      inbox+         inbox/DELETE
    mh-users_tosave    mh-users=ve/DELETE mh-workers     reference
    reference/DELETE
    
Section Explanation of fols explains how to set up fols.

Folder Stacks

If you're changing your current folder between two or more folders over and over, you might want to use a folder stack. A folder stack is a set of folder names that MH saves for you. You arrange the stack with the folder command and its -push and -pop switches. Folder stacks work a lot like the C shell's directory stacks.

Overall Description of a Folder Stack

First, I'll describe a folder stack. Think of a desktop. On the desk are your current folder and a stack of other folders from a file cabinet. In the Figure below, the current folder is reports/jan. To check which folder you're in, use folder:

    % folder
         reports/jan+ has   2 messages (  1-   2); cur=  2.
    
On the stack, there are three other folders; the reports/feb folder is on the top.

Figure: Current folder and folder stack

cufoafos.jpg

To get a list of the current folder and the stack, type:

    % folder -list
    reports/jan reports/feb friends friends/Annie
    
As you can see when you compare the -list output to the Figure above, the first folder listed is the current folder. The rest of the list is the folder stack, top folder first.

How did the stack get there? MH "remembers" the list of folders on the stack the same way it remembers the current folder. (In the context file.) You can keep the same stack as long as you want and change it at any time. You can add or remove folders from the stack (see the following example). So there's no one answer for "how" the stack got this way. But, assuming that the stack was empty when you started, these commands would have created it in the shortest time:

    % folder -fast
    friends/Annie
    % folder -push +friends
    % folder -push +reports/feb
    % folder -push +reports/jan
    
The first command showed that the current folder is friends/Annie. The last three commands pushed three more folders on the stack and left reports/jan as the current folder. In real life, a folder stack usually grows more slowly.

If you use folder stacks a lot, typing folder -push and folder -pop over and over can get tiresome. This is a good place to use shell aliases or functions. There are some useful aliases for folder stacks.

Pushing a Folder onto the Stack

If you want to move the current folder to the top of the stack and get a new current folder, use folder -push +foldername. For instance, the command that would make the desktop look like the next Figure (making inbox current and moving reports/jan to the top of the stack) is:

    % folder -push +inbox
    inbox reports/jan reports/feb friends friends/Annie
    
folder automatically does a -list, which displays the current folder followed by the other folders on the stack.

Figure: After pushing reports/jan onto the top of the stack

aprottot.jpg

Going to Previous Folder

To swap the current folder with the top of the stack, use folder -push by itself. As the next Figure shows, this puts inbox on the stack and makes reports/jan current:

    % folder -push
    reports/jan inbox reports/feb friends friends/Annie
    

Figure: After swapping current folder with top of stack

afscfwto.jpg

Popping a Folder Off the Stack

To replace the current folder with the top of the stack (and not push the current folder onto the stack), use the -pop switch. If your shell has a "repeat-last-command" feature, you can use it to pop another folder. For example, here we pop inbox off the stack (and make it the current folder). Then we pop reports/feb off, too, using the C shell's history operator !! (you could also just type folder -pop again). Watch the folder list change:

    % folder -pop
    inbox reports/feb friends friends/Annie
    % !!
    folder -pop
    reports/feb friends friends/Annie
    
NOTE: The folder command can change the current message. For example, the command folder +junque 23 will change the current folder to junque and the current message in junque to 23.

But folder -push will ignore message numbers and won't change the current message unless you also use the -print switch. This might be considered a bug.

I used to avoid using folder stacks because typing a command like folder -push takes some effort. I started by making shell aliases named puf and pof -- for "push folder" and "pop folder," respectively. Those made folder stacks easier. But I still couldn't pop a folder from the middle of a stack, as I can use a shell directory-stack command like popd +2 to remove the second directory from the stack.

A script changed that. It has multiple names: puf and pof, like the aliases; lsf, to list the folder stack; clrf, to clear (remove all folders from) the stack; and (finally!) pof1, pof2, ..., pof8 to pop the first, second, eighth, etc. folder from the stack. For example:

    % folder -fast
    inbox
    % lsf
    inbox
    % puf +apes
    apes inbox
    % puf +boas
    boas apes inbox
    % puf
    apes boas inbox
    % puf +cats
    cats apes boas inbox
    % puf +dogs
    dogs cats apes boas inbox
    % lsf
    dogs cats apes boas inbox
    % pof
    cats apes boas inbox
    % pof3
    cats apes boas
    % clrf
    folder: folder stack empty
    % lsf
    boas
    
To install this script and all its links, see the section Explanation of pof and Friends.

Renumbering Messages in a Folder

After removing and rearranging messages in a folder, there can be gaps in the numbering. For instance, if your inbox folder has messages 1-25 and you remove any ten messages, the other message numbers won't change. To renumber the messages 1, 2, 3, ..., use the command:

    % folder -pack
               inbox+ has  15 messages (   1-  15); cur=  1.
    
Really big folders with lots of gaps can cause errors. The NOTE in Section Previous-Sequence, Sequence-Negation explains why. It's a good idea to keep big folders packed.

In MH 6.8.3, folder -pack has a new -verbose option that shows you the steps it's following to renumber the messages.

Working in an MH Directory

When you use standard MH commands like show or rmm on a mail folder, you never need to cd (change directory) into the folder. But there are times that it's easier, or more efficient, to cd into a directory and run commands on the messages and subfolders there. If you haven't read the Chapter Key Parts of the UNIX Filesystem, please browse it before you go on.

The easiest way to cd to a folder is with the mhpath command:

    % cd `mhpath +somefolder`
    
Without the somefolder, mhpath gives the pathname of the top-level MH directory. Without any arguments (no +), you get the pathname of the current folder.
NOTE: This book isn't a UNIX tutorial. Before you use any of the commands in this section that delete or move message files and folders, be sure you understand what the commands do. If you aren't sure, check a good UNIX reference or ask a local expert.
This section gives examples with specific commands, but you can use the same ideas in other situations. For example, the techniques in the section on copying messages can be used for moving messages with mv(1), transferring them to another computer with rcp(1), and so on.

Renaming and Moving Folders

One way to change the name of a mail folder is to make a new folder, use refile all to move all the messages into it, then remove the old (empty) folder. But it's faster to cd to the top-level MH directory and use mv(1) to rename the folder without moving any messages. That method is a lot faster if you're trying to rename a folder and all its subfolders! For example, to rename project to project.old, start by using ls to be sure that there isn't already a project.old folder:

    % cd `mhpath +`
    % pwd
    /home/ehuser/Mail
    % ls -F
        ...
    ollie/     project/     recipes/   replcomps
    % mv project project.old
    
If project had any subfolders, they've become subfolders of project.old.

Most versions of mv can also move directories to different levels -- that is, to make a directory become a subdirectory. That's how to make a folder into a subfolder. For example, if you have top-level folders named for your friends (+brandi, +randy, +mandy) and you want to make them subfolders of a new +friends folder:

    % folder +friends
    Create folder "/home/ehuser/Mail/friends"? y
    % cd `mhpath +`
    % mv brandi randy mandy friends
    

Finding Recently-read Messages

UNIX keeps track of the last time a file was accessed (read). You can use this information to find a message you read earlier today. Maybe this morning you read a message in your status folder, which has 500 messages from employees. But now your current message is different. Using pick or scan might help, if you can narrow down the search. But you can also use ls -lut to list the messages in the folder with the most-recently-accessed messages first. If the folder has a lot of messages, pipe the output to head (or sed 10q) to see just the first few lines:

    % ls -lut `mhpath +status` | head -7
    total 1974
    -rw-------  1 ehuser        490 Nov 14 09:22 27
    -rw-------  2 ehuser       1352 Nov 13 14:12 153
    -rw-------  1 ehuser       7824 Nov 13 14:12 151
    -rw-------  2 ehuser       8469 Nov 13 14:12 149
    -rw-------  1 ehuser       3969 Nov 13 14:12 148
    -rw-------  2 ehuser       2154 Nov 13 14:12 147
    
Aha. The last message you read, at 9:22 on the morning of November 14, was message 27. Note that the other messages were all accessed at the same time -- the last message number first. pick and scan also read messages; they reset a file's last-access time too. Messages 153 and earlier were probably scanned or picked on the afternoon of November 13. So, if you use the ls method to find a message, try it before you search with pick or scan!

Using Shell Wildcards

MH has message number ranges like 25-34 and last:10, and sequences like unseen. Those work from any current directory, of course. Once your current directory is the same as the folder, though, you can use shell wildcards to create lists of message numbers or subfolders. For example, if you want to forward messages 10, 20, 30, ..., 90, 100, 110, ..., 170, you could type all of those message numbers. Or you could cd to the current folder and let the shell do the work:

    % cd `mhpath`
    % forw [1-9]0 1[0-7]0
    
If you aren't sure how that works, cd to the folder and use the echo command instead of forw.

Wildcards are even handier for getting a list of folders or subfolders. If you want to search through a series of folders named month1 through month12 and year1 through year3 but not year4 on, you could pipe the output of folders -fast through a complex egrep(1) expression to get a list of folder names. Or you could cd to the top-level MH directory, where the folder directories are, and let the shell make the list of names:

    % cd `mhpath +`
    % foreach folder (month? month?? year[1-3])
    ? echo Checking +$folder...
    ? scan `pick -subject SUMMARY +$folder`
    ? end
    Checking +month1...
    pick: no messages match specification
    scan: no messages match specification
    Checking +month2...
     930   2/14 To:Bob Cosman      January SUMMARY<<Bob, the January shipments were
        ...
    
The shell expands the wildcards into a list of directory names. To make month1 through month9 come out before month10 through month12, I used separate expressions: month? month??. (If I didn't care about the order, month* would have been easier.) Adding a + (plus) to the variable's value made each directory name into a folder name. (Here's more information about shell loops.)

Copying Messages

There's no MH command for copying messages to another folder. The MH refile -link command makes a link, not a separate copy. Say you want to make a backup copy of the messages in an important folder. Create the backup folder, then cd into the source folder and use cp(1):

    % folder +project.bak
    Create folder "/home/ehuser/Mail/project.bak"? y
    % cd `mhpath +project`   ...changes current directory, not current folder
    % cp * `mhpath`
    
That series of steps deserves some careful thought. It copied all the messages (*) from the current directory (the project folder) into the current folder (project.bak). If you wanted to make the backup copies more secure, you could write-protect the project.bak folder and the messages in it:
    % cd `mhpath`
    % chmod a-w . *
    
That last command takes away write permission for everyone to the current directory (.) and all the messages in it (*).

cding into the current folder can be more efficient than using mhpath to make a long list of pathnames. For example, you could have copied all messages from project into project.bak with a command like this:

    % cp `mhpath all +project` `mhpath +project.bak`
    
But, to copy those messages, cp would have needed to search the long pathname to each source message (/home/ehuser/Mail/project/1, /home/ehuser/Mail/project/2, etc.) over and over. To save the path searching, it's better to cd to the source directory. That lets cp find the files directly (1, 2, etc.).

If you don't want to copy a range of messages that you can match with wildcards -- or by simply typing the message numbers (filenames) on the command line -- the msgnums command version might do the job. It expands MH message ranges and sequences into the message numbers that make them up. Let's say that you've read through a folder, finding messages you want to copy to your personal computer and adding them to the temp sequence. To pass the message numbers to kermit -s, which sends the files over a telecommunications link (a modem, for example):

    % cd `mhpath`
    % kermit -s `msgnums temp`
    
If the temp sequence held messages 10-12, 44, and 69, the shell would run the command kermit -s 10 11 12 44 69.

You can copy MH messages to remote hosts with networking commands like ftp. Just cd to the MH folder and use get or mget to grab the message files you want. (If you have a lot of messages to transfer, it's more efficient to archive them with tar and gzip first, then transfer the archive.) If you're writing the messages into an MH folder, be sure that the new messages don't overwrite existing ones. An easy way to be sure is to create a new MH folder, temporarily, on the destination host -- transfer the messages into it -- then use refile to move the transferred messages safely into the folder where they belong.

Cleaning out Folders

Seems like my workstation disk is always filling up with mail. Using rmm doesn't make a difference. (The Section Removing and Recovering Messages explains why.) Sometimes I have to do major surgery. If I'm looking for big messages, I'll cd to a particular folder or the top-level MH directory -- and have find(1) hunt through folders and subfolders for big messages to remove. When find finds a file bigger than 100 blocks, I have it execute scan -file to list the message, then ask me whether to run rm to remove it. scan -file gets the message number wrong; this doesn't matter because I can see the folder and message number in the prompt:

    % cd `mhpath +sources_etc`
    % find . -size +100 -type f -exec scan -file '{}' \; -ok rm '{}' \;
       1  05/27 Jerry Sweet        stacknews - a utility for handling USENET news v
    < rm ... ./mh/22 >?   n
       1  01/23 Bill Wohler        mailarch-1.4: archive MH mail<<this is mailarch 
    < rm ... ./mh/47 >?   n
       1  09/27 John Lamperitz     interesting WWW guide<<Found this interesting ti
    < rm ... ./web/6 >?   y
    
In that example, find found three big messages: numbers 22 and 47 in the +sources_etc/mh subfolder, and number 6 in +sources_etc/web. I told it to remove the web message.

When you use rm to remove a file, it's gone for good. Unlike the default rmm, using rm saves disk space right away.

rm has one other advantage over MH message-removing utilities: rm can remove folders and subfolders in one pass. Removing a whole folder tree is tough with MH commands: rmf won't remove a folder that contains subfolders. You have to start from the bottom level, remove the subfolders, then remove the folder(s) above. If you're sure that you want to remove a folder, and all of its subfolders, just use rm -r. Here's how to remove the top-level junque folder and any subfolders:

    % cd `mhpath +`
    % ls
    ...  junque  ...
    % rm -r junque
    

Archiving Folders

Because MH stores each message in a separate filesystem block, the blocks will have some unused space. If you have a folder that you don't use very often, you can save space by packing the messages into a tar(1) archive compressed with gzip(1) or compress(1). When you need the folder back, you can extract some or all of it.

Here's how to archive the folder named big, and any subfolders, into a gzipped file named big.tar.gz:

    % cd `mhpath +`
    % tar cvf - big | gzip > big.tar.gz
    a big/1 42 blocks
    a big/2 247 blocks
       ...
    % ls -l big.tar.gz
    -rw-r--r--  1 ehuser    1167386 Nov 14 09:34 big.tar.gz
    % rm -r big