Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

How can I determine if there is unread mail on my OSX box?

Mail is fetched from a variety of places with fetchmail, and delivered to my local user in /var/mail/user. I am searching for a way to find out if there is unread mail, or if I have read the mail (using alpine). I prefer a solution that uses unix tools, but am open to AppleScript or any other solution for the unread count part, but it must work with unix mail readers (/var/mail/user).

I'd like to have a command line tool that says if there is unread mail in the inbox, so that I can run it with a cron job, and use the keyboard_leds tool to set subtle notifiers. I prefer this to MacBiff, growlnotify, etc.

I thought I figured out one possible solution:

mail -H | grep -c '^.[NU]'

seems to sometimes return the number of unread messages. But if I read a message in alpine, it doesn't update until I quit alpine.

Another approach might be to use my mail client (alpine) directly. I have a clean .pinerc which has no colors, etc trying to make the display as simple as possible, and then run this command:

alpine -o -x .pinerc.clean -I i,q >& foo

Which runs alpine, goes to the Inbox, and then quits (leaving the inbox in read-only mode so as to not disrupt my main alpine process which is viewing the inbox). The screen dump of the inbox is stored in the file "foo".

However, foo the last screen (quitting message, not inbox) and is a binary file in this case, and I cannot figure out how to parse it for the "N" in the column that designates unread mail, even if it were there...

share|improve this question
Is this a question or a blog? And are you going to award the bounty to yourself, yourself or yourself? Please group all your trials and conclusions into your post, delete all your answers and define clearly your question. At the moment it's quiet hard to understand what is exactly the point here. –  harrymc Sep 8 '10 at 20:56
This is a question. The FAQ states, "...Document your own continued efforts to answer your question.", which is what I was doing. –  user31752 Sep 8 '10 at 22:37
I know it says that and it's not a bad thing, it merely becomes hard to understand your progress when it's divided over 3 answers and the question itself! =) –  BloodPhilia Sep 8 '10 at 23:02
It's much clearer when you restrict yourself to your post and let others supply the answers, even if you have found the answer yourself. –  harrymc Sep 9 '10 at 10:36
add comment

4 Answers

up vote 2 down vote accepted

You're 90% of the way there with the mail -H | grep -c '^.[NU]' command. I understand that you need this to reflect any changesd made in an open instance of Alpine however. Unfortunately this is not easy to do, but I'll lay it out for you anyway.

What you want is not directly possible because the changes to Message Status made by Alpine are done so in memory and only written out to disk periodically (at "checkpoints"). The mail command (and all variants) can only read mail information from disk, and cannot know of changes made in Alpine between checkpoints. So all you can really do is increase the frequency of checkpoints.

The code to determine when to checkpoint is very complicated but from what I can gather the default settings:

  • Won't save any more often than 180 seconds (min_interval)

  • When Alpine has been idle for more than 30 seconds it will checkpoint if 12 changes (checkpoint frequency) to the file have been made or at least one change has been made and a checkpoint hasn't been done for five minutes (*checkpoint_interval*).

  • When Alpine has executed some command it will checkpoint if there are 36 outstanding changes to the mail file or at least one change and no checkpoint for ten minutes.

  • When composing a message Alpine will only checkpoint if at least 48 changes have been made or at least one change has been made in the last twenty minutes with no checkpoint.

What you really want is for Alpine to write back to disk more frequently. Unfortunately the checkpoint_interval and checkpoint_frequency variables can only be changed at compile time. To do this you need to recompile Alpine, but with some configure options, namely:

--with-checkpoint-interval (default 420)
--with-checkpoint-frequency (default 12, you might want to change to 1) 

Of course, if you're going to go to the trouble of recompiling alpine you may just want to change the checkpoint code to write after each change, but be warned that whatever you do, it's likely to result in decreased performance if you increase checkpointing frequency.

One more thing to note - you can see when checkpoints occur currently by turning on the option [X] Enable Mail Check Cue. Two asterisks ** will appear when it is saving to disk.

share|improve this answer
Thanks for the answer. I've recompiled with --with-checkpoint-frequency=1 and it does not seem to save after every change... I'm not too worried about performance as my inbox is local (not IMAP) and has only a few messages in it at any given point in time. –  user31752 Sep 15 '10 at 19:37
OK upon further reading of the code this cannot be configured only with options to ./configure. There are hard-coded #DEFINE statements in the code to limit frequency... –  user31752 Sep 15 '10 at 19:51
Good to know, especially since it seems to contradict the linked newsgroup post. Good luck getting to do do what you want. This is why open source is cool (though oft painful)! –  imoatama Sep 15 '10 at 23:44
add comment

Try the following script:


if [[ "$?" == "0" ]]
    then echo "You've got mail!"
    else echo "No new mail"

Replace the echo commands to suit your purpose.

share|improve this answer
checkmail doesn't seem to exist on OS X nor in fink. Can you provide a link to the source? –  user31752 Sep 8 '10 at 22:45
@mankoff check out mj.ucw.cz/linux.html –  BloodPhilia Sep 8 '10 at 23:01
Doesn't seem to compile under OS X. Also, based on the issue with mail/mailx NOT seeing mail as "read" until I quit alpine, I'm not sure that checkmail will have more success... –  user31752 Sep 8 '10 at 23:10
add comment

See this article : A script to only show unread/flagged messages in Mail.app Apps:

It's a shame Mail can't display unread/flagged only messages .. or can it? Correct me if I'm wrong. Anyway, here are two scripts to filter your mailbox. Save these scripts inside Users -> your_username -> Library -> Scripts -> Mail Scripts -> anySubFolder. They'll appear under the script icon on Mail menubar. In case you don't know, you can also add shortcut keys to the scripts; I'm too lazy to tell you how, but you can open up Mail Help and find the instruction under Browse Mail Help -> Customizing Mail -> Using the Scripts Menu.

The article contains two scripts : Show unread only and Show flagged only, which not being a Mac person I can't evaluate. However, if they work, they can be easily adapted to your needs.

Here is Show unread only :

  tell application "Mail"
    set theViewer to front message viewer
    set theMsg to messages of theViewer
    set msgList to {}
    repeat with thisMsg in theMsg
      if read status of thisMsg is false then
        set the end of msgList to thisMsg
      end if
    end repeat
    if msgList is {} then
      display dialog "There's no unread message in this mailbox."
      tell theViewer to set properties to {visible messages:msgList}
    end if
  end tell
  on error the errMsg number the errNmb
  if the errNmb is not -128 then
    set the errTxt to "Error: " & the errNmb & ". " & the errMsg
    display dialog the errTxt buttons {"Cancel"} default button 1
    error number -128
  end if
end try
share|improve this answer
I don't use Mail.app and this solution requires use of Mail.app. It won't work with /var/mail/user... –  user31752 Sep 9 '10 at 14:02
Sorry. I'll leave this answer here for the benefit of users of Mail.app. –  harrymc Sep 9 '10 at 14:34
add comment

See if this article helps : Command-line mail on OS X: re-alpine and Geektool

While looking for remote monitoring tools at the office this week, I ran across GeekTool. GeekTool is like SilverService for notifications. All it does is display something on the desktop. At the office I’ve quickly started using it to monitor log files and remote graphs. But the shell output option is perfect for displaying incoming mails.

/usr/bin/mail -H

This is just the command-line mail program with the option to display the index of waiting mails and immediately quit. If there are messages waiting, it will display the message date and subject, and if not it will display nothing.2

So this will leave the desktop alone, unless there is mail waiting to be read from one of my cron jobs.

GeekTool is pretty cool, and you can download a bunch of pre-made “geeklets” for it (I haven’t used any of them). You can place them on the desktop and arrange them as you see fit.

share|improve this answer
No as you can see from the question, re-written at your advice, I've already tried this and explained the limitations. –  user31752 Sep 9 '10 at 19:34
add comment

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.