TimeMachine unmount assistant

jesseshipley
Contributor

Thought I'd share this for anyone that might be interested. I've rolled out 100 or so TimeMachine drives to users who leave them plugged into their Thunderbolt Displays for convenience. The problem quickly arose that no one was remembering to eject their drives before unplugging from their monitors and backups are corrupting. To help with this I written a script that creates a LaunchAgent to eject any TimeMachine backup disks when the power cable is unplugged. This way users only have to unplug their MagSafe first.

I've tested it on 10.9 and 10.10. It must be run as root and it requires CocoaDialog (though that is easy to modify if needed.)

#!/bin/sh
#make scripts dir if it doesn't exist
if [ ! -d /Library/Scripts/Company ]; then
    mkdir /Library/Scripts/Company
fi

#unload the LaunchAgent incase it was previously installed
launchctl unload /Library/LaunchAgents/com.company.ejector.plist

#delete LaunchAgent and script in case they were previously installed
rm -f /Library/Scripts/company/ejector.sh
rm -f /Library/LaunchAgents/com.company.ejector.plist

#create LaunchAgent
echo '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Label</key>
        <string>com.company.ejector.plist</string>
        <key>ProgramArguments</key>
        <array>
                <string>/Library/Scripts/Company/ejector.sh</string>
        </array>
        <key>WatchPaths</key>
        <array>
                <string>/private/var/root/Library/Preferences/com.apple.telemetry.battery.charge-cycle.plist</string>
        </array>
</dict>
</plist>' > /Library/LaunchAgents/com.company.ejector.plist

#create ejector.sh script
echo '#!/bin/sh
plug=$(defaults read com.apple.telemetry.battery.charge-cycle PlugTime | awk '"'"'{print $1" "$2}'"'"' | sed '"'"'s/[-|:| ]//g'"'"')
unplug=$(defaults read com.apple.telemetry.battery.charge-cycle UnplugTime | awk '"'"'{print $1" "$2}'"'"' | sed '"'"'s/[-|:| ]//g'"'"')
if ! $(tmutil destinationinfo | grep -q Mount); then
    echo "No TimeMachine volume mounted"
    exit 0
elif [ $plug -ge $unplug ]; then
    echo "Plugging in instead of unlugging"
    exit 0
else
    rm -f /tmp/ejector
    mkfifo /tmp/ejector
    /Applications/Utilities/CocoaDialog.app/Contents/MacOS/CocoaDialog progressbar --indeterminate --title "Eject" --text "Ejecting backup..." --icon usb < /tmp/ejector &
    exec 3<> /tmp/ejector
    tmutil destinationinfo | grep Mount | awk '"'"'{print $NF}'"'"' | xargs -I{} diskutil unmountDisk {}
    exec 3>&-
    rm -f /tmp/ejector
    /Applications/Utilities/CocoaDialog.app/Contents/MacOS/CocoaDialog msgbox --title "Eject" --text "It is safe to disconnect" --button1 OK --icon usb
    exit 0
fi' > /Library/Scripts/Company/ejector.sh

#make ejector.sh executable
chmod +x /Library/Scripts/Company/ejector.sh

#load the LaunchAgent
launchctl load /Library/LaunchAgents/com.Company.ejector.plist
exit 0
0 REPLIES 0