A set of scripts to unmount drives before sleeping

When I’m at home, my MacBook Pro is hooked up to an external display, a couple of hard drives, and other peripherals. When I need to go on the road, I put it to sleep, unplug all the peripherals, and away I go.

There’s only one problem: Unplugging a hard drive can corrupt its filesystem if it’s still mounted. To prevent that from happening, I wrote a script that automatically unmounts all drives. As an added bonus, the script fails if any of those drives are busy and can’t be unmounted, warning me to take additional action before hitting the road. Here it is:

tell application “Finder”
    eject (every disk whose ejectable is true)
end tell

In most cases, this simple script works great, but it suffers from a few drawbacks:

  1. It ejects not only hard drives, but optical discs as well, which is usually not what I want.
  2. It won’t eject remotely mounted drives, such as NFS or AFP mounts.
  3. It won’t work if Finder is not running, which may be the case for PathFinder users like myself.

To fix these issues, I split the script into two parts, one for local drives and one for remote drives, and I rewrote it so that optical discs would be left alone. Here’s the part that unmounts local drives:

-- Set this list to the names of the local drives
-- you want to unmount
set local_drives to [“Backup drive”, “Clone”]

repeat with drive in local_drives
   
   set drive to “/Volumes/” & drive
   set driveExists to false
   
   try -- Ignore AppleScript warnings
      do shell script “test -d ” & ¬
            quoted form of drive
      
      -- Test completed successfully; drive exists
      set driveExists to true
   end try
   
   if driveExists then
      -- Eject the drive
      do shell script "umount " & ¬
            quoted form of drive
   end if
   
end repeat

And here’s the part that unmounts the remote drives:

-- Set this list to the names of the remote drives
-- you want to unmount
set remote_drives to [“DreamHost”, “DOC”]

repeat with drive in remote_drives
   
   set drive to “/Volumes/” & drive
   do shell script “umount ” & ¬
         quoted form of drive
   
end repeat

I don’t eject optical drives, but if for some reason you need to do so, here’s how:

-- This will eject the optical disc in the
-- primary (built-in) drive
do shell script “drutil -drive 1 eject”

-- This will eject all discs in all optical drives
do shell script “drutil eject”

For a downloadable version of these scripts, see my AppleScript page.

11 Responses to “A set of scripts to unmount drives before sleeping”

  1. Michael says:

    How do you make this run as a default when you put the computer to sleep?

  2. Trevor says:

    I have a script called “Sleep” that runs these unmount drive scripts, along with other housekeeping tasks, then tells the computer to sleep. I simply run it manually. If you’re looking for an automated solution, try SleepWatcher.

  3. Ron says:

    I am looking for a good way to sleep my laptop and unmount a few drives. The issue I am coming up with is a Sleep script. Can you please send me a copy of yours.

    TIA

    P.S. Sleepwatcher is not what I am looking for 😉

  4. Trevor says:

    The following script will put the computer to sleep:

    tell application “Finder” to sleep

  5. […] Trevor’s Bike Shed » Blog Archive » A set of scripts to unmount drives before sleeping There’s only one problem: Unplugging a hard drive can corrupt its filesystem if it’s still mounted. To prevent that from happening, I wrote a script that automatically unmounts all drives. As an added bonus, the script fails if any of those drives are busy and can’t be unmounted, warning me to take additional action before hitting the road. […]

  6. Eric3 says:

    With the simple script you initially mentioned, the third drawback can be overcome by changing the middle line to:

    eject (every disk whose ejectable is true or local volume is false)

  7. Shortland says:

    Any way that I can apply this to my DSDT? I’m running an EFI patched verion of Snow Leo on a non mac (for experimentation) and this is the only issue I haven’t found a fix for yet – which doesn’t make alterations to the native system install..

  8. oschrenk says:

    The script for ejecting local drives was giving me Operation not permitted errors.

    What helped was using diskutil unmount instead of umount

  9. Steve B. says:

    Nice info and a great starting point. I’d like to give a little something back now that my problem is solved. I found that the above technique would not quite work for me as it falls short with USB flash drives. Use of an applescript calling Finder to unmount a flash drive destroys all traces of it such that calling diskutil to remount it after wakeup fails. Using the following 2 commands below will successfully unmount and then remount any and all connected USB drives AND leave your integrated optical drive alone …

    unmount:

    ls /dev/disk* | grep ‘disk[1-9]s[1-9]’ | xargs -I{} /usr/sbin/diskutil umount {}

    remount:

    ls /dev/disk* | grep ‘disk[1-9]s[1-9]’ | xargs -I{} /usr/sbin/diskutil mount {}

    Aloha !

  10. Tim Kimpton says:

    Thanks Steve B

    does this also work on mounted network shares as well?

    Im looking for a solution to unmount all external media and drives except optical

    Thanks

  11. Doug says:

    @Steve…I’m sure you can get something to work for mounted drives, however you mount them you can unmount.

    @All, why use umount or unmount. Seems using eject with diskutil is much safer for letting unwritten files to be saved. (Based on the man pages and is what I am planning to use.

Leave a Reply to Shortland