[Updated 23 March 2013]
A couple of readers, Jan and frankspage (see comments below) has recently pointed to me that the script I provided below still does not allow the newer SSD MacBook Airs and MacBook Pro Retina to go into deep sleep mode. It looks like unmounting the SD Card isn’t enough and you really do need to eject out the drive. So I’ve decided to completely re-write my article to reflect all the new findings that was made and largely thanks to Jan who has provided a lot of insights into how to get this to work.

I’ll also be taking into consideration a new set of users that are using this guide to help with the use of the Nifty MiniDrive where the primary eject and re-mount is for the SD card.

So here’s a special thanks to Jan and frankspage for their invaluable inputs to improve this article and in effect, everyone of us that has used this trick. Do help me to spread out the word on this update to anyone you know who are using this guide, especially to those who are using it with the Nifty MiniDrive.


Let’s face it. There’s just never enough storage space on your MacBook. Especially so if you use an SSD (or two in my case) where the GB/$ ratio, while getting better, is still prohibitive if you want to have more than 500GB on your MacBook.

My point is, you’d likely have to deal with a portable external hard disk in your daily work. And if you are like me, all you do is just shut the lid to allow the MacBook to go to sleep and never ever shut it down in between work. So there you go, shutting the lid and then unplug the external hard disks. Then you remembered that you didn’t eject the disks first! So what do you see when you open up the lid again?

Not Ejected Properly

Yup. That dreaded “The disk was not ejected properly” dialog box.

Darn it, Apple!

Why can’t the OS X just auto eject the disk when it goes to sleep?

The Nifty MiniDrive and the removal tool

And then there are also the bunch of us that has used the generally idle SD Card slot to expand the MacBook’s storage. This is especially popular amongst the 128GB and 256GB MacBook Air and MacBook Pro Retina users where a Micro SDXC card is used along with the popular Nifty MiniDrive.

But why do you want to auto-eject the Nifty MiniDrive when it’s always plugged in? Isn’t that totally opposite from the point of this article? Well, it seems that with the newer SSD only MacBook Air and MacBook Pro Retinas has a new standby mode and the SD Card prevents the Mac from going into this standby mode. See the Apple support documentation here.

And if you’re wondering, the Mac notebooks that support standby mode are:

  • MacBook Pro (Retina, 13-inch, Late 2012 and later)
  • MacBook Pro (Retina, 15-inch, Early 2013 and later)
  • MacBook Pro (Retina, Mid 2012)
  • MacBook Air (Mid 2010) and later

But there is an added complexity with this group of users as you would want an easy way to also auto-remount your always inserted Nifty MiniDrive since you would not want to always unplug and replug the MiniDrive back. And as I’ve discovered, once the SD Card is ejected, your Mac would not ‘see’ the SD Card anymore and thus, would not be able to remount the card when you want it to.

So that’s the premise of this article, to find a way to auto-eject your mounted drives and upon waking up the Mac, auto-remounting any drives that is still connected.

And while we are at it, perhaps maybe you also want to have a way to auto eject any connected network drives? This is especially useful if you don’t want to get any disconnection errors such as when you start using your Mac at work just after leaving from home for example. It could sometimes be embarrassing if you use funny names for your shared network drives and then have it prominently displayed as an error message when you connected your Mac to a projector for a early morning presentation at the office. :)

Anyways, I thought that there must be a way that you can execute a script when MacBook goes to sleep. And there surely is also a way to script the ejection of the disks. And as always, Google was the answer and sure enough, I found two ways to do it as well as another great tip from a reader, Jan.

So here are the 3 different ways to do it, each with increasing difficulty to implement them with their pros and cons. But even if the recommendations below may seem complex and scary especially to those of you who are not familiar with using the terminal and running command line scripts, don’t be too afraid to try. I’m putting in extra care to ensure the instructions are as complete as possible and with as much screenshots as possible to guide you through. And if all fails, please do drop me a comment and I’ll help you out as much as I can to get it working for you.

Recommended: Please do read the entire article before working you start to implement whichever methods you wish to so that you completely evaluate all the steps.

Let’s get started!

Method 1: Auto Eject only (Easiest)

As it seems, this frustration is not new (*duh*) and there are a couple of applications on the Mac App Store that do exactly this, auto eject any disk that you like to upon sleep. The first app is called Jettison priced at $1.99.

Jettison Screenshot
Jettison Jettison - St. Clair Software

The other app is called autoEJECTV priced slightly more expensive at $2.99.

AutoEJECT
autoEJECTV autoEJECT - dragonBTV

Both apps auto-ejects the disks as promised. However, it does not remount ejected SD Cards and USB flash drives, which is why I put this down as an auto-eject only option since it’s not a full proof solution.

The Pros: The advantage of this method is obvious. It’s easy since it’s built as an app. No brainer to install.

The Cons: Unfortunately it doesn’t always automatically remount your ejected disks, and especially so for ejected SD Cards as most of us has discovered. Plus, it’s not free. :)

Method 2: Using Sleepwatcher and auto un-mounting/re-mounting script

The second method here is to use a utility called SleepWatcher. It runs as a daemon and monitors the sleep activity of your MacBook and provides you the ability to executes scripts when the sleep mode activates and vice versa.

So now, what we have is a way to unmount and remount disks upon sleep and wake of the MacBook! But why using un-mount instead of ejecting a disk? As I mentioned above, ejecting has the effect of not allowing you to easily remount your ejected disks. You’d need to physically unplug and replug the disk back to your MacBook for it to be detected and remounted again. This may not be an issue with USB connected external HDDs but for the likes of the Nifty MiniDrives, this isn’t all that fun to do. But before I go on with this method, I also mentioned above that there is a downside to this step, especially if your MacBook is one of the newer ones that support a new Standby mode and do want to use this Standby mode. It seems that un-mounting prevents standby mode from working. So the only way is to eject the disk which also complicates how you would automatically re-mount the disk.

So if that’s the case, is this method still relevant for MacBooks that supports standby mode? It depends on one more thing. Do you also use Power Nap? This is because Power Nap also prevents your MacBook from going into standby mode! If so, then you might as well just un-mount and re-mount all external disks since its never going into standby mode. But if you do want to have standby mode working, go on towards Method 3 after installing Sleepwatcher as that is still required. I’ll let you know when to skip ahead.

Installing Sleepwatcher (Required for Method 2 AND 3)

To install Sleepwatcher, simply download the latest version of SleepWatcher (link here). Once downloaded, extract the tgz archive in the Downloads folder if it’s not already done so automatically.

Downloaded and extracted Sleepwatcher to the download folder. Please take note of the folder name.

Downloaded and extracted Sleepwatcher to the download folder. Please take note of the folder name.

The current version of Sleepwatcher as of the update of this article is version 2.2 and therefore the name of the folder you would see is sleepwatcher_2.2. If otherwise, you would need to change the following commands to be as per the latest name of the folder.

Beginners tip: To open up Terminal, hit the command+space key to use Spotlight and then type in terminal to quickly find the app. Press enter to run it.

Use Spotlight to quickly open up Terminal

Use Spotlight to quickly open up Terminal

Now, to install Sleepwatcher, just run the following commands in Terminal. The first command below will require you to enter your Mac’s password. Just enter the password and the command will execute. These commands would not

sudo mkdir -p /usr/local/sbin /usr/local/share/man/man8
sudo cp ~/Downloads/sleepwatcher_2.2/sleepwatcher /usr/local/sbin
sudo cp ~/Downloads/sleepwatcher_2.2/sleepwatcher.8 /usr/local/share/man/man8
Copying the required Sleepwatcher files to the rightful locations

Copying the required Sleepwatcher files to the rightful locations

Next, we need to ensure that SleepWatcher is launched every time OS X starts up. The download includes a sample configuration plist file that we would use. And I’ll shorten up the file name in the copy command below.

sudo mv ~/Downloads/sleepwatcher_2.2/config/de.bernhard-baehr.sleepwatcher-20compatibility-localuser.plist ~/Library/LaunchAgents/de.bernhard-baehr.sleepwatcher.plist
sudo chown root ~/Library/LaunchAgents/de.bernhard-baehr.sleepwatcher.plist
sudo chmod 644 ~/Library/LaunchAgents/de.bernhard-baehr.sleepwatcher.plist
sudo launchctl load ~/Library/LaunchAgents/de.bernhard-baehr.sleepwatcher.plist
Loading the configurations and allowing sleepwatcher to always run on start

Loading the configurations and allowing sleepwatcher to launch everytime your MacBook starts up

At this point, you’ve successfully installed SleepWatcher. And if you are planning to use method 3, WAIT! There’s one more thing to do before moving on.

We have to get to know a little bit more of about your MacBook and this can be slightly tricky. You see, the method I’m using is not to eject the disks but to unmount the volumes. Unlike the command to eject disks, there is the danger of unmount the hard disks that your OS X is running on. Therefore, it’s important that you check using the following commands in order to filter out the hard disks that you *do not* want to be unmounted.

Don’t worry, I’ll step you through what you need to do.

On Terminal and run the following command.

/usr/sbin/diskutil list

You should see something like the follwing:-

List of disks

List of disks

In most cases, disk0 is where your main hard disk is installed (Macintosh HDD). And if that is the only hard disk you have installed on your MacBook, then you’d want to unmount anything that’s mounted as disk1 and above. This should be true for most MacBook Air and MacBook Pro Retina users since there is only one SATA interface and only one SSD installed. However, if you use FileVault on your MacBook, some of you may still find that the external disks is mounted as disk2. in that case, then you’d only want to unmount anything that’s mounted as disk2 and above.

In my specific case, disk0 is where my Samsung 830 256GB SSD is mounted to and disk1 is where my Intel 320 Series 300GB SSD is mounted to. Both of these disks are the ones that I DO NOT want to be unmounted at any point in time. That means the ‘magic number‘ for me is disk2 and above.

So let’s keep this ‘magic number‘ is disk1 or disk2 depending on your MacBook’s configurations.

Remember, this is an important step that you should not skip especially since I’m providing a sample script in my guide below. You’ll need to edit the provided script if your ‘magic’ number is disk2 like mine is.

Method 3 skipping point. Ok. If you want to proceed on with method two on just un-mouting, continue on. Otherwise, it’s time to skip over to Method 3 below.

Let’s move on to create the scripts. Again, if you’re even the slightest bit unsure, just drop me a comment and I’ll gladly help you along.

The next step is to create the sleep and wakeup script that SleepWatcher will execute. All you need to do is to use a text editor (I highly recommend using TextWrangler) and create the following files and save both of them on your Desktop.

Sleep script

To create your own sleep.txt, copy and paste the following two lines, and then save the file on the Desktop.

#!/bin/sh
/usr/sbin/diskutil list | grep -e 'disk[1-9]s.*' | sed 's/.*\(disk[0-9].*\)/\1/' | xargs -I{} /usr/sbin/diskutil unmount {}

Now, if your ‘magic number‘ is disk1, then you don’t need to change that line. Otherwise, if it’s disk2, the you will need to change the grep -e ‘disk[1-9]s.*’ to grep -e ‘disk[2-9]s.*’. Essentially, you are just changing the filter of which the script uses to determine which disks to unmount.

Wakeup script

Next, the wakeup.txt script. And do the same with the …disk[1-9]… as you did with the sleep script if your ‘magic number‘ is disk2.

#!/bin/sh
/usr/sbin/diskutil list | grep -e 'disk[1-9]s.*' | sed 's/.*\(disk[0-9].*\)/\1/' | xargs -I{} /usr/sbin/diskutil mount {}

Here’s an extra step if you’re using FileVault on your MacBook. You will need to delay the script from running immediately from wakeup. This is to ensure that you have already unlocked the file system before the script runs, which otherwise has the effect of ejecting the external disks. In order to do that, just add add a sleep command with the a delay time (in seconds) that is comfortable enough for you to enter your password. The example below shows a delay of 5 seconds. Credit goes to Jan for providing us this valuable feedback.

#!/bin/sh
sleep 5
/usr/sbin/diskutil list | grep -e 'disk[1-9]s.*' | sed 's/.*\(disk[0-9].*\)/\1/' | xargs -I{} /usr/sbin/diskutil mount {}

If this confuses you too much, don’t worry. You can also download the files here (link) and extract them to the desktop and make sure both the files are on your desktop so that you can just copy and paste the following scripts. But remember to edit them if you want to unmount disk2 and above, and if you use FileVault or not.

The sleep and wakeup scripts on the Desktop

The sleep and wakeup scripts on the Desktop

Done? Great! Now, you need to move the files into your home directory as .sleep and .wakeup which SleepWatcher will execute based on the launch configurations. To do so, open up Terminal and run to following commands.

mv ~/Desktop/sleep.txt ~/.sleep
chmod a+x ~/.sleep
mv ~/Desktop/wakeup.txt ~/.wakeup
chmod a+x ~/.wakeup

And that’s all to it for method 2! Now, your MacBook would automatically unmount and eject all the external disks and mounts it back when you wake up your MacBook again!

The Pros: This scripts works really well for all disks, including USB flash drives and there’s no need to forcefully reload any drivers (Method 3) to remount any disks.

The Cons: Requires a little bit of Terminal tinkering. But most of all, prevents standby mode for the newer MacBooks.

Method 3: Using Sleepwatcher with the auto-ejecting and force remounting scripts

Disclaimer: I didn’t come up with this 3rd method and full credit goes to Jan (see the comments below) for contributing the following steps.

Firstly, remember that you’d still need to install Sleepwatcher. To do so, just follow the steps I’ve provided in method 2. Once you are done with Sleepwatcher, use the following scripts for sleep.txt and wakeup.txt.

Sleep script

Use a text editor to create the sleep.txt file, copy and paste the following two lines, and then save the file on the Desktop. The main difference here with this script is the use of eject instead of unmount.

#!/bin/sh
/usr/sbin/diskutil list | grep -e 'disk[1-9]s.*' | sed 's/.*\(disk[0-9].*\)/\1/' | xargs -I{} /usr/sbin/diskutil eject {}

And just as in method 2, if your ‘magic number‘ is disk1, then you don’t need to change that line. Otherwise, if it’s disk2, the you will need to change the grep -e ‘disk[1-9]s.*’ to grep -e ‘disk[2-9]s.*’. Essentially, you are just changing the filter of which the script uses to determine which disks to eject.

Wakeup script

This is the tricky one. It seems that with Mountain Lion, when you use the diskutil eject command, the Mac would no longer be able to remount SD cards and USB flash drives. However, external HDDs whether on USB or FireWire (and I’m assuming Thunderbolt) interfaces can still be remounted. So such, a simple command to remount like method 2 would not work.

The trick then is to force the remount process by reloading the drivers for the USB ports and SD Card reader and this can be particularly tricky as it would require you do find out which are the drivers you would need to use for the commands below.

But before that, let’s allow the driver reload command executable without needing passwords. Otherwise, it would not run the script automatically upon wakeup.

Go to terminal and enter the following command.

sudo visudo

You’ll see the following screen.

visudo

visudo

For those of you who are unfamiliar with VI (http://en.wikipedia.org/wiki/Vi), what you are looking at is basically a text-based editor that’s available in all Unix-based system. Don’t worry, you don’t have to be an expert with vi in order to do what you need to do here. Just follow the following steps and you’ll be fine. And no, the mouse will not move the cursor, this is old-school text editing! :)

1. Press “i” to enter editing mode. You’ll see the word INSERT appear on the bottom left of the Terminal window.

Edit mode enabled

Edit mode enabled

2. Hit the down arrow key till you reach the User privilege specification section.

Go to the User Privilege Specification section

Go to the User Privilege Specification section

3. At the end of that section add the following. Remember to replace [YOUR USERNAME] with your username.

[YOUR USERNAME] ALL=(ALL) NOPASSWD: /sbin/kextunload, /sbin/kextload

Not sure what your username is? Just look at the Terminal window. That’s your username right up there!

There's your username :)

There’s your username :)

Beginner’s tip: Hit enter for a new line at the cursor point just below the %admin… row. Type your username. Then hit the tab key and then type in the rest of the line: ALL=(ALL) NOPASSWD: /sbin/kextunload, /sbin/kextload. You should then see the following screenshot.

Visudo edited!

Visudo edited!

4. You’re done with the required edit! Now hit the Escape key (esc). This takes you out of the edit mode. You should no longer see INSERT at the bottom left of the screen.

5. Type “:wq” (without the quote marks) and hit enter. This will write the file and quit vi.

 

:wq to save and quit

:wq to save and quit

6. Done! To make sure what you’ve just did works, type in the following command “sudo kextload” and it should not ask you for any password. Don’t worry, the command does nothing.

Sudo kextload don't ask for password anymore!

Sudo kextload don’t ask for password anymore!

Now that that’s done, Let’s move on to the wakeup script.

In this script, we still want to use the diskutil mount command. Even though the SD Cards and USB flash drives would not be automatically re-mounted, this command would still remount any external HDDs that are still connected.

For the SD cards, this can be slightly tricky. The key is to know which specific driver to reload. For the newer MacBooks that has support for SDXC, then the driver to reload is com.apple.driver.AppleSDXC. For the rest, it would be com.apple.driver.AppleUSBCardReader.

According to Apple’s support site, the following Macs supports SDXC cards.

  • MacBook Pro (Early 2011 and later)
  • MacBook Air (Mid 2011 and later)

However, based on feedbacks that I’ve got, the following might help you avoid the need to check which driver is the one to use.

If you’re using a MacBook Pro Retina, I’m pretty certain the driver is com.apple.driver.AppleSDXC, so you can safely skip checking for the right drivers to reload.

If you’re using a MacBook Pro that’s Mid-2010 and earlier, and a MacBook Air Early 2011 and earlier, the driver will be com.apple.driver.AppleUSBCardReader.

But the surest one way to know is to just try and unload the two drivers to see which one ‘force ejects’ your SD Card. Now before you do this, make sure you don’t have any applications that is using your SD Card or that any write activity is happening onto the SC card since the commands below it will forcefully eject your card.

Using the note from Apple as a guide, determine which of the following command you would want to try first, if it ejects your card, then that’s the driver to use. Otherwise, try the other command and see if it ejects now. Either way, you should know which is the driver to use.

Go to Terminal and enter the following command in Terminal for all MacBook Pro Retina, MacBook Pro (Early 2011 and later) and MacBook Air (Mid 2011 and later).

sudo kextunload -b com.apple.driver.AppleSDXC

OR for any other MacBooks.

sudo kextunload -b com.apple.driver.AppleUSBCardReader

Try to get the above right the first time. Once you know which one is the driver to use, do not attempt to keep testing one or the other again. In my testing for this article update, it seems to have a weird effect of not working anymore, while for Jan who contributed this method, it works for him consistently, perhaps knowing from the start that AppleSDXC is the driver to use on his MacBook Pro Retina.

I’ve also gotten feedback that the trick above does not always work, so if anyone could find a way to ascertain which drivers to use, it would be super helpful.

So here’s the required wakeup.txt script!

For AppleSDXC driver

#!/bin/sh
/usr/sbin/diskutil list | grep -e 'disk[1-9]s.*' | sed 's/.*\(disk[0-9].*\)/\1/' | xargs -I{} /usr/sbin/diskutil mount {}
sudo kextunload -b com.apple.driver.AppleSDXC; sudo kextload -b com.apple.driver.AppleSDXC

For AppleUSBCardReader driver

#!/bin/sh
/usr/sbin/diskutil list | grep -e 'disk[1-9]s.*' | sed 's/.*\(disk[0-9].*\)/\1/' | xargs -I{} /usr/sbin/diskutil mount {}
sudo kextunload -b com.apple.driver.AppleUSBCardReader; sudo kextload -b com.apple.driver.AppleUSBCardReader

Again, remember do the same with the …disk[1-9]… as you did with the sleep script if your ‘magic number‘ is disk2.

And as mentioned in method 2, if you’re using FileVault on your MacBook. You will need to delay the script from running immediately from wakeup. This is to ensure that you have already unlocked the file system before the script runs, which otherwise has the effect of ejecting the external disks. In order to do that, just add add a sleep command with the a delay time (in seconds) that is comfortable enough for you to enter your password. The example below shows a delay of 5 seconds. Add it just below the #!/bin/sh line.

Update [March 30, 2013]:

Based on a recent comment from a reader (see comments from Stewart below), I think that it would be useful to add the delay anyway. It seems that in some cases, the kext load/unload would not remount the SD Card if it ran immediately upon wakeup. So the sleep command to delay the scripts seems to help. Just add the delay time as per shown below. The script below forces a delay of 5 seconds.

#!/bin/sh
sleep 5
...

Now all you need to do is to move the files into your home directory as .sleep and .wakeup which SleepWatcher will execute based on the launch configurations. To do so, open up Terminal and run to following commands.

mv ~/Desktop/sleep.txt ~/.sleep
chmod a+x ~/.sleep
mv ~/Desktop/wakeup.txt ~/.wakeup
chmod a+x ~/.wakeup

Wait, what about USB flash drives?! Ah, as I discovered, the driver to reload is com.apple.iokit.IOUSBMassStorageClass. However, it looks like Mountian Lion OS does not allow the driver to be unloaded using the kextunload command. But since USB flash drives are easily repluggable, I’ll just leave it as that.

The Pros: This scripts will allow your MacBook to go into Standby mode.

The Cons: Requires a a lot more Terminal tinkering, including some vi editing.

Uninstalling Sleepwatcher and the scripts

If you ever wanted to uninstall and remove sleepwatcher from your MacBook, just run the following commands to delete everything you created as per the above.

sudo launchctl unload ~/Library/LaunchAgents/de.bernhard-baehr.sleepwatcher.plist
sudo rm ~/Library/LaunchAgents/de.bernhard-baehr.sleepwatcher.plist
sudo rm /usr/local/sbin/sleepwatcher
sudo rm /usr/local/share/man/man8/sleepwatcher.8
rm ~/.sleep
rm ~/.wakeup

You should now have sleepwatcher and its scripts removed.

SanDisk 64GB 64G microSDXC microSD microSDHC SD SDHC SDXC Card Mobile Ultra Class 10 UHS-I with R10W Reader SanDisk 64GB 64G microSDXC microSD microSDHC SD SDHC SDXC Card Mobile Ultra Class 10 UHS-I with R10W ReaderSanDisk 64GB microSDXC Mobile Ultra Retail Package With SD Adapter UHS-I Class 10 *Free USB 2.0 Card Reader Included (R10W) Speed Class Rating: Class 10






Please Google +1 my article if you think it was useful. Thanks!

Check out the following posts too!