Time Machine Auto-mount/unmount Drive OS X

I have a USB backup drive connected through my monitor to my Macbook Pro and I often find myself wanting to quickly unplug and go without the consequences of the drive not being ejected properly. As well, I need the drive to be mounted so that Time Machine can do its automatic backups.

Well I found a way to avoid having to manually mount and unmount (eject) my drive by using shell scripts and LaunchAgents to achieve the task. The added benefit is that I have control over the timing of the frequency of the Time Machine backups too!

Note: This works on OS X Lion or later.

Step 1

Create a plain text file named timemachine_mounter.sh with the following contents:

#!/bin/bash
# Set the drive name that we mount for our backups 
vol_mount="Time Machine"
# Conditional argument: if mounted entry has the volume name in the variable string
if ! mount | grep "$vol_mount" ; then
	# Drive isn't mounted, so: mount. A LaunchAgent will pick this OnMount action up and run the backup script
	diskutil mount "$vol_mount"
else
	# Drive is mounted, so: run the backup script
	timemachine_backup.sh
fi

Save the file in the /usr/local/bin/ directory at the base of your system drive. You may need to first save the file to your desktop then use finder to move it to that directory, it will ask to authenticate. Or use sudo in Terminal to move the file there instead, and make sure that ownership belongs to you (the user that logs in), in my case the assigned user:group was mike:staff.

Step 2

Create a plain text file named timemachine_backup.sh with the following contents:

#!/bin/bash
# Set the drive name that we mount for our backups 
vol_mount="Time Machine"
# Conditional argument: if mounted entry has the volume name in the variable string
if mount | grep "$vol_mount" ; then
	# Drive is mounted, so: backup and then eject after
	tmutil startbackup -b && 
	diskutil eject "$vol_mount"
fi

Save the file in the /usr/local/bin/ directory again with the same ownership credentials as the previous script.

Step 3

Create a plain text file named com.apple.TimeMachine_OnLoadSchedule.plist with the following contents:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN http://www.apple.com/DTDs/PropertyList-1.0.dtd>
<plist version="1.0">
<dict>
	<key>Label</key>
	<string>com.apple.TimeMachine_OnLoadSchedule</string>
	<key>RunAtLoad</key>
	<true/>
	<key>StartInterval</key>
	<integer>7200</integer>
	<key>Program</key>
	<string>/usr/local/bin/timemachine_mounter.sh</string>
</dict>
</plist>

Save the file in the ~/Library/LaunchAgents/ directory inside your User folder/directory (~/).

What the above file does is register in the system to run the mounter script:

  • when I first log in
  • consecutively every 2 hours

Step 4

Create a plain text file named com.apple.TimeMachine_OnMount.plist with the following contents:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN http://www.apple.com/DTDs/PropertyList-1.0.dtd>
<plist version="1.0">
<dict>
	<key>Label</key>
	<string>com.apple.TimeMachine_OnMount</string>
	<key>StartOnMount</key>
	<true/>
	<key>Program</key>
	<string>/usr/local/bin/timemachine_backup.sh</string>
</dict>
</plist>

Save the file in the ~/Library/LaunchAgents/ directory as well.

What the above file does is register the system to run the Time Machine backup script whenever the drive gets mounted. This can happen when:

  • I physically connect the drive
  • the scheduler LaunchAgent above, runs the driver mounter script

In Terminal, make sure the shell scripts are executable, unload the default plist (if you didn't turn off your Time Machine automatic backups in the System Preferences) and finally load the new LaunchAgent in your local LaunchAgent startup folder:

chmod +x /usr/local/bin/timemachine_*.sh
sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.backupd-auto.plist
launchctl load ~/Library/LaunchAgents/com.apple.TimeMachine_OnMount.plist
launchctl load ~/Library/LaunchAgents/com.apple.TimeMachine_OnLoadSchedule.plist

Lastly...

You can change the com.apple.TimeMachine_OnLoadSchedule.plist's integer value for the starting interval 7200 integer to something more reasonable (e.g., 3600 seconds is one hour,... multiply at will.) I have my backups run every two hours.

The good thing about using a LaunchAgent is that:

  • if your computer goes to sleep or is shut off, the backup will begin at the next time you log in and reset the countdown from that point onward
  • if Time Machine is already running it won't try to run the process until the next projected sync time
  • if the drive is freshly connected or mounted already, Time Machine will begin backing up your changes and eject after its done
Share Button

Tags: , , , , , , , , , , ,

  • Michael Shulman

    I believe this line:

    chmod +x /bin/automount_timemachine.sh

    should be:

    chmod +x /bin/timemachine_*.sh

    -ms

    • http://www.somethinginteractive.com/ Michael J Kormendy

      Ahh yes, that will work nicely! Thanks for the revision!

      • dwain0Wilder

        Fascinating. I found this while looking for just this solution, in order to increase lifetime by not having the Time Machine volume sat idly spinning.

        But I have a MacBook duo-core on snow leopard (10.6.8). Will this script work there?

        • http://somethinginteractive.com/ Michael J Kormendy

          I do believe it should, but I cannot be certain since all of my machines that run the script are using Mavericks. Give it a try!

  • jason

    I cannot get the plist from steps 3 and 4 to load. I consistently get a “nothing found to load” error.

    I copied the scripts above to a textedit document, saved and then changed the extension to a .plist before copying both files into the ~/Library/LaunchAgents/ folder.

    I’m at a loss for what is going wrong. Any help would be greatly appreciated!

    • http://www.somethinginteractive.com/ Michael J Kormendy

      Can you clarify,… which scripts did you paste into the plist?
      There are four files in total, each with separate content.

      As a rule, plists don’t necessarily contain “scripts”.

      But .sh files (are shell scripts).

      • jason

        Thanks for the quick replies!

        In steps 1 and 2, I copied and pasted each script you provided into their own textedit file and saved each according to your naming provided. Next I changed the file name to a .sh and moved them into the /bin folder (Macintosh HD –> bin) folder.

        Next I copied the contents in steps 3 and 4 into their own textedit file and named each according to your naming scheme. I renamed the extension of each file to a .plist and I saved each into the ~/Library/LaunchAgents/ folder (I figured out the difference in the two LaunchAgents locations with some googling but was stuck there for a bit).

        Everything seems to be OK until I get to here:

        launchctl load ~/Library/LaunchAgents/com.apple.TimeMachine_OnMount.plist
        launchctl load ~/Library/LaunchAgents/com.apple.TimeMachine_OnLoadSchedule.plist

        and that is where I get the nothing found to load error. Also, how do I know if the chmod +x /bin/timemachine_*.sh command actually works? I don’t get any errors so I assumed it did, but when I open up that folder the files are still shown as a text file and not a Unix Executable File.

        This setup is exactly what I’ve been searching for, but terminal is new to me so I’m learning as I go. Thanks for the help!

        • http://www.somethinginteractive.com/ Michael J Kormendy

          Did you make sure to make your textedit file a plain text file? See the attached image for details on how to do that.

          Generally, Terminal doesn’t give you a “completed” response, if it was successful at its commands … it often just sends you back to the prompt.

          • jason

            That worked! Now, another (hopefully final) question.

            I never logoff my machine and instead sleep it when I’m stepping away. Then, I wake and login to unlock it when I return. Can the script be modified to backup upon wakeup/unlock instead of at login and an interval following? I assumed this would occur this way, but I guess unlocking isn’t treated the same and logging in.

            This modification appears to be working great otherwise and is otherwise exactly what I’ve been trying to do for a long time. Thank you.

          • http://www.somethinginteractive.com/ Michael J Kormendy

            Ask yourself this: are you going to be having files change while your computer is asleep?

            If not: then the most recent backup would likely be the last one that was performed when your computer was last awake. So you don’t need to run a backup if nothing gets changed while your system was asleep.

            If you do, you somehow have files change while your computer is asleep or locked: this is very rare, and I don’t necessarily know how to address that. There’s no system on wake-up event programmed into LaunchD that I know of.

          • jason

            My thought for having it backup when I wake my Mac from sleep and unlock/login was because sometimes take a quick look at email in the morning and then disconnect it from my monitor and head out the door. Since I wouldn’t necessarily know at what time my backup from the night before ran, it would be nice to leave knowing a backup just ran.

            In reality and the more I think about it, it’s not a big deal and I can always manually mount the drive and have it run a quick backup before I disconnect it if I need to.

            All your help with this was much appreciated!

          • http://www.somethinginteractive.com/ Michael J Kormendy

            There are some solutions that you could install from this discussion online here:

            http://apple.stackexchange.com/questions/27036/possible-to-run-scripts-on-sleep-and-wake

            Then just direct them to run timemachine_mounter.sh and that will mount the drive. Once that occurs, the system will recognized that the drive is newly mounted and then start the backup.

    • http://www.somethinginteractive.com/ Michael J Kormendy

      Also make sure that you placed the plists into ~/Library/LaunchAgents/ and not /Library/LaunchAgents/
      (note the “~” before)

      If you place the files into the “~” prefixed folder, that will go into the user’s LaunchAgents that load up when they log in. Otherwise, you are attempting to load LaunchAgents from the system startup (before logging in).

      I chose to only have backups happen while I am logged in, because, well, essentially that’s the only time when my files are being changed and need to be backed up.

  • jason

    Hi Mike, have you tested this with Mavericks yet? Just curious if it works…. this has been working great for me with Mountain Lion since you helped me through my issues and I don’t want to lose this functionality.

    Thanks!

    • http://www.somethinginteractive.com/ Michael J Kormendy

      I have installed mavericks, and the job hasn’t loaded due to issues with permissions and user ownership, and thus it skips the job. However I do not know why the system says “Dubious ownership on file (skipping)”, if nothing changed, and other jobs in the same directory have the same ownership and permissions.

    • http://www.somethinginteractive.com/ Michael J Kormendy

      Well, I found out that Installing Mavericks has deleted the two shell script files that we used to place in the root bin directory. That being said, I recreated them and placed them in the /usr/local/bin/ directory (where they really should be after researching more). I made them executable again by using the command in the post. Then I edited the two plist files to reflect the new locations of the .sh files. Then I reloaded both of them by running a launchctl unload -w command on the two plist files in their ~/LaunchAgents/ directory, then the load command in the post as well.

      I’ve edited the post to reflect all of the changes. If you follow the steps again, you’ve already done half of the work.

      • jason

        Hi Mike,

        I made the changes you discussed and followed the steps again. I thought I had everything working but turns out the volume wasn’t mounting on its schedule. If I mounted it manually the backup would run. So, I went back in and went through the steps again. I realized I never unloaded the old .plist files from steps 3 and 4 before so I ran launchctl unload -w ~/Library/LaunchAgents/com.apple.TimeMachine_OnMount.plist and launchctl unload -w ~/Library/LaunchAgents/com.apple.TimeMachine_OnLoadSchedule.plist then continued with loading the new .plist with
        launchctl load ~/Library/LaunchAgents/com.apple.TimeMachine_OnMount.plist and

        launchctl load ~/Library/LaunchAgents/com.apple.TimeMachine_OnLoadSchedule.plist When attempting to load both .plist files, I get “nothing found to load” and no idea what I’m missing. Do you have any suggestions as to where I’m going wrong? Thanks!

        • http://www.somethinginteractive.com/ Michael J Kormendy

          Are you sure you’re pointing to the correct filenames of the plists? I think I may have cleaned that up to reflect a more semantic naming of what the plists do.

          • jason

            I’m positive I am. It just seems the plist’s do not want to load. I know there has to be an easy explanation for it, but I’m not sure what it is. Did I unload the prior plist’s correctly?

          • http://www.somethinginteractive.com/ Michael J Kormendy

            if you type:

            nano ~/Library/LaunchAgents/com.apple.TimeMachine_OnLoadSchedule.plist

            … and it comes up blank — then you’re not pointing to the correct file location. They are not in your User Folder’s LaunchAgents folder (be sure that you’re placing it in your User defined LaunchAgents directory for the load command to work .. (that’s what the “~” is for)

            To get out of nano press ctrl+x

          • jason

            Doing that command returns the OnLoadSchedule.plist in terminal so that seems okay…

          • jason

            Through terminal, I was able to execute the two .sh files to verify that they ran and they did so I confirmed my issue came down to the 3rd and 4th lines of the commands above. After creating completely new .plist files with no luck, I modified each command line to read:

            sudo launchctl load -w -F ~/Library/LaunchAgents/com.apple.TimeMachine_OnMount.plist

            and

            sudo launchctl load -w -F ~/Library/LaunchAgents/com.apple.TimeMachine_OnLoadSchedule.plist

            and they both loaded (finally). Do you know why this modification would be necessary and is it okay to run this way?

            Thanks for all your help and suggestions!

          • jason

            It seems that what really goofed something up was when I ran

            launchctl unload -w ~/Library/LaunchAgents/com.apple.TimeMachine_OnMount.plist

            and

            launchctl unload -w ~/Library/LaunchAgents/com.apple.TimeMachine_OnLoadSchedule.plist

            earlier so the newly modified plist could be loaded. Did I do something wrong here?

          • http://www.somethinginteractive.com/ Michael J Kormendy

            Please try this:

            launchctl list | grep Time

            Do any entries come up?

          • jason

            If I paste the line above directly into terminal and hit enter, nothing comes up.

          • jason

            The two load commands work just including the -w (without the sudo or -F like I posted above) to force load the plist. From what I’ve been reading, the message “nothing found to load” means that the config is overriden by another config. You force the loading by using the option “-w” when using launchctl load or unload. When having to force the load or unload of a plist file, it means that you have a config which overrides the plist. This overriding is created when you use the “-w” otherwise no override will be added to the overrides file. To prevent this, it sounds as though the plist can be modified but I’m not sure what needs to be modified.

            I should have noted earlier that this setup is on a brand new Macbook Pro that came with Mavericks installed. I had no problems on my prior machine which I upgraded to Mavericks shortly before I sold it although Mavericks did delete the two .sh files (as you mentioned occurred to you in your initial post) so I had to copy them back over into the bin folder and everything work flawlessly again.

          • http://www.somethinginteractive.com/ Michael J Kormendy

            go to your ~/Library/LaunchAgents/ folder and type:

            ls -Gal

            Is there an @ symbol beside the permissions for the plists? If so, perform the next command:

            xattr -l com.apple.TimeMachine_On*

            What do the two entries say at the end?

          • jason

            I do get an @ symbol for both of them. Here’s what I get:

            JRS-Macbook-Pro-447:LaunchAgents JRS$ ls -Gal

            -rw-r–r–@ 1 JRS staff 423 Dec 1 00:34 com.apple.TimeMachine_OnLoadSchedule.plist

            -rw-r–r–@ 1 JRS staff 367 Dec 1 00:35 com.apple.TimeMachine_OnMount.plist

            JRS-Macbook-Pro-447:LaunchAgents JRS$ xattr -l com.apple.TimeMachine_On*

            com.apple.TimeMachine_OnLoadSchedule.plist: com.apple.TextEncoding: utf-8;134217984

            com.apple.TimeMachine_OnMount.plist: com.apple.TextEncoding: utf-8;134217984

            Now what?

          • http://www.somethinginteractive.com/ Michael J Kormendy

            okay .. I just wanted to make sure that there weren’t any extra bits assigned to the file that were blocking them from loading up. Seems like you figured it all out though.

          • jason

            Thanks again for all your help!

          • http://www.somethinginteractive.com/ Michael J Kormendy

            That’s good, there are no actively running processes with the word “Time” in their process name.

          • jason

            I think I figured it out… if I use -w to unload the two LaunchAgents, then I have to include -w to load them again. However, if I unload them without using the -w then I can load them without the -w and can use your 4 lines of script above exactly. I don’t know nearly enough about how these commands work to know why it worked this way but it’s working. See below:

            JRS-Macbook-Pro-447:~ JRS$ launchctl unload -w ~/Library/LaunchAgents/com.apple.TimeMachine_OnMount.plist

            JRS-Macbook-Pro-447:~ JRS$ launchctl load ~/Library/LaunchAgents/com.apple.TimeMachine_OnMount.plist

            nothing found to load

            JRS-Macbook-Pro-447:~ JRS$ launchctl unload -w ~/Library/LaunchAgents/com.apple.TimeMachine_OnLoadSchedule.plist

            JRS-Macbook-Pro-447:~ JRS$ launchctl load ~/Library/LaunchAgents/com.apple.TimeMachine_OnLoadSchedule.plist

            nothing found to load

            JRS-Macbook-Pro-447:~ JRS$ launchctl list | grep Time

            ——————————————————————
            JRS-Macbook-Pro-447:~ JRS$ launchctl unload ~/Library/LaunchAgents/com.apple.TimeMachine_OnMount.plist

            JRS-Macbook-Pro-447:~ JRS$ launchctl unload ~/Library/LaunchAgents/com.apple.TimeMachine_OnLoadSchedule.plist

            JRS-Macbook-Pro-447:~ JRS$ chmod +x /usr/local/bin/timemachine_*.sh

            JRS-Macbook-Pro-447:~ JRS$ sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.backupd-auto.plist

            JRS-Macbook-Pro-447:~ JRS$ launchctl load ~/Library/LaunchAgents/com.apple.TimeMachine_OnMount.plist

            JRS-Macbook-Pro-447:~ JRS$ launchctl load ~/Library/LaunchAgents/com.apple.TimeMachine_OnLoadSchedule.plist

          • http://www.somethinginteractive.com/ Michael J Kormendy

            Your bash scripts should work fine regardless of the plists for the launch agent.