5

Quite simply, I have a process that's triggered by launchd but currently runs once an hour, however really what I would like it to do is run once a Time Machine backup has completed.

Initially I thought I could just set my Time Machine backup (/Volumes/Foo/Backups.backupdb/Haravikk's Mac) as a watch path for launchd, however this seems to trigger much too early. It does seem to trigger again near the end, so I'm currently using a delay and then checking for the existence of a .inprogress backup, but it's not really an ideal solution, and sometimes Time Machine's cleanup stage will trigger the process multiple times.

Is there a more specific path that I could watch that will trigger my process only when Time Machine has finished a backup?

I realise I should perform my checks anyway to be sure, but currently my process is triggering several times per backup, which isn't what I want.

2 Answers 2

4

Okay, so after setting up a launch agent to log information for a while I've come up with a combined solution.

Quite simply I created a launch-agent that watches the com.apple.TimeMachine.plist file for updates like-so:

 <?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>org.example.backupd</string>
    <key>ProgramArguments</key>
    <array>
        <string>do something</string>
    </array>
    <key>WatchPaths</key>
    <array>
         <string>/Library/Preferences/com.apple.TimeMachine.plist</string>
     </array>
 </dict>
 </plist>

This file is updated every time Time Machine performs a backup, and runs towards the end (during the cleaning up/finishing stage I believe). With this in mind it is possible to invoke a script with the above watch path that checks to see if backupd is still running; if it is then the script sleeps for a minute and checks again, repeating until backupd has finished, before proceeding with whatever it needs to do.

This now allows post-backup actions to be triggered such as performing secondary backups (in my case via rsync to a NAS), checking the size of the last backup and other handy things.

Anyway, this solution seems to be the best way to do it, as I couldn't find any path to watch that triggers reliably after a backup is complete, but this should run close enough to the end of a backup to be useful.

1
  • This works very well. You do not need to check again a minute later since the plist action will also be triggered at the end of the backup (maybe just wait a few seconds before checking). Also, checking backupd does not work with the latest MacOs versions. However, you can use the undocumented tmutil status to check if the backup is still running. Apr 14, 2023 at 6:40
3

A simple solution is to use the tmutil command to manually trigger the backup and follow it up with your process (as part of a shell script that does both these steps).

  • First, turn off automatic backups from System Preferences > Time Machine or using the command tmutil disable
  • Use tmutil startbackup --auto --block to trigger a backup once every hour (the --block option is required to make the execution wait until the backup is finished)
  • Follow this with launching your process

See man tmutil for more information on using Time Machine from the command line.

2
  • That would be ideal, and I could maybe make it work, but I was really hoping to be able to make my script a "drop in" addition, leaving Time Machine to function normally (I just don't want to be running at the same time). Is there perhaps a way to look out for backupd running and just wait till it finishes before running my script?
    – Haravikk
    Nov 5, 2013 at 11:43
  • I just tried creating and running a wrapper program for backupd, but it runs once every 10 seconds and exits. So monitoring backupd is not useful.
    – M K
    Nov 5, 2013 at 15:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .