What is the best approach to ejecting disk while in sleep mode, scheduled?

So, I have an external HDD which is being used for Time Machine.

After getting to home, I usually connect my MacBook to a HDD via Hub and put it into sleep mode. Because I sometimes get back home late during the night, the Time Machine backup may happen during midnight. However, in the morning I have to wake up my mac, only to safely eject the HDD and put the MacBook into sleep mode again for bringing my MacBook out.

So I searched in order to create a scheduled disk eject job that can be run during sleep. I looked for solutions like crond, launchd, but even launchd cannot run a script during sleep mode if I properly understood the documentation - even if I set up a job with StartCalendarInterval it will not be invoked until the MacBook is woken up.

Is there any commercial app or another approaches that can be used for my situation?

My OSX is latest version of Mojave.


Solution 1:

I think the Energy Saver suggestion is a good place to start:

 » System Preferences » Energy Saver » Schedule and set it for, say, 30 minutes before you want to leave for work.

However, I would not schedule it to go back to sleep unless you know that it has actually succeeded in ejecting the disk. Otherwise you might have the disk not eject for some reason, and then if you remove the drive, you'll get that terrible message about ejecting a drive improperly.

So, let's say that you want to leave for work at 8:00 a.m.

Set Energy Saver to wake the computer at 7:30 a.m.

Then I would use Keyboard Maestro to run a script at 7:35 a.m. to unmount the drive. (You can schedule specific times for macros in Keyboard Maestro.)

The first step of the macro would be a shell script to unmount the drive.

I have a shell script to do this already, so I'm sharing it here. You can add a shell script as a step of a Keyboard Maestro macro.

All you'd need to do is change the DRIVE="/Volumes/Time Machine" line to reflect where your Time Machine drive mounts.

#!/bin/zsh -f

    ## Change this to wherever your Time Machine drive mounts
DRIVE="/Volumes/Time Machine"

    ## Change this to however many times you want to try before
    ## the script considers itself to have failed.
MAX_ATTEMPTS="100"

    ## Only change this if you know you need to
PATH=/usr/local/bin:/usr/bin:/usr/sbin:/sbin:/bin

    ## initialize the counter. Don't change this :-)
COUNT=0

    ## This `while` loop will keep going until the drive no longer appears at the mount
    ## point, or we exceed the number of attempts we defined above.
while [[ -d "$DRIVE" ]]
do
        # increment counter
    ((COUNT++))

        # check to see if we have exceeded maximum attempts
    if [ "$COUNT" -gt "$MAX_ATTEMPTS" ]
    then

        echo "Exceeded '$MAX_ATTEMPTS' trying to eject '$DRIVE'."

            ## This will cause the script to fail
            ## which should cause the Keyboard Maestro macro to fail
            ## so it won't go to sleep, so you'll know that you
            ## have to manually eject the drive
        exit 1
    fi

        # don't sleep the first time through the loop
    [[ "$COUNT" != "1" ]] && sleep 10

        # This is where we try to eject the drive
    diskutil eject "$DRIVE"

done

exit 0

The second step of the macro is a built-in feature in Keyboard Maestro to Put Computer To Sleep.

However, if the first step of the macro fails (i.e. if the drive does NOT eject) then the computer will not go back to sleep.

Solution 2:

You can schedule your MacBook to wake before your scheduled disk eject job and then go back to sleep afterward (something like wake up at 5:00, sleep at 5:05 and your eject job in the middle).

from Apple support :

  1. From the Apple menu, choose System Preferences, then click Energy Saver.

  2. Click the Schedule button, then use the checkboxes and pop-up menus to choose when to start up, wake, sleep, restart, or shut down.