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.
% 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:
% 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 | moreOr, if you don't really need to see all of your messages, you can scan a range of messages:
% scan last:20The Section Find and Specify with scan, pick, Ranges, Sequences shows other choices.
% 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 testYour 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.
Two MH commands accept folder name arguments but don't change the current folder:
% refile +junk 45 47The 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.
To move messages out of your current folder into another folder, use refile +foldername, where foldername is the destination folder. 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 messageYou refiled the current message into test. So the second scan and show tell you that there's no current message. (By the way, your current folder is still inbox.)
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
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 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 woIf 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 thatTo link message 1 from inbox into both the junk and test folders, use:
% refile -link +test +junk 1Now 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
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 +doneThe same thing done in two steps would look like this:
% folder +project project+ has 23 messages ( 1- 47); cur= 1. % refile 1 3 5 +doneEither way you do it, after refile finishes, your current folder will be project. Unlike plain refile, the refile -src switch changes the current folder.
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.)
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"? yYou 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.
% 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/AnnieBecause you're already in the friends folder (your current folder), it would be nice not to have to type its name. You can do that 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 dCompare the two examples. Think how much more typing you'd need without the short folder names....
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: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.
% 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:
% 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.
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 friendsThe -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/JosephAs 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.
% 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.
% fols -r drafts drafts/DELETE inbox+ inbox/DELETE mh-users_tosave mh-users=ve/DELETE mh-workers reference reference/DELETESection Explanation of fols explains how to set up fols.
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
To get a list of the current folder and the stack, type:
% folder -list reports/jan reports/feb friends friends/AnnieAs 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/janThe 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/Anniefolder 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
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
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.
% 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 has a new -verbose option that shows you the steps it's following to renumber the messages.
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.
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.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.
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.oldIf 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 147Aha. 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]0If 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.
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:
% 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.
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 >? yIn 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
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
[Table of Contents] [Index] [Previous: Sending Files; Using mhmail and viamail] [Next: Finding Messages with pick]
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>