Excessively Adequate

Popping up a Notification When a macOS App Stops Running

On my laptop, in lieu of the official Dropbox client (which does a lot, much more than I need, which is: keeping a folder in sync), I’ve been using Maestral for a couple of years now. It works beautifully except on rare occasions when it silently crashes – it’s a known issue, difficult to reproduce, and the developer’s working on it. One of these days it’ll be fixed and I’ll rejoice.

Until then, I’d rather not get caught out working on old versions of stuff, so I’ve implemented an extremely basic watchdog in the form of a Bash script that 1. checks if anything called “Maestral” is running on my system and, if not, 2. lets me know about it by popping up a notification.

#!/usr/bin/env bash

if ! pgrep Maestral; then
    osascript -e 'display notification "It probably crashed, so try starting it manually." with title "Maestral might not be running!"'
fi

There’s not much to it: The pgrep utility allows you to look up running processes by name, printing any matching process IDs to standard output. If no matches are found, it returns a non-zero exit code, meaning that by inverting it using !, the body of the conditional is executed when Maestral is not running (i.e., when it’s most likely crashed). An easy way of displaying notifications is provided by osascript, the native AppleScript interpreter.

I have my computer run this script every five minutes as a good ol’ cron job, for which I’ve appended the following line to my crontab (edit yours by running crontab -e):

*/5 * * * * bash "path/to/script.sh"

In this specific case, an alternative solution would involve adjusting Maestral’s launchd configuration, adding <key>KeepAlive</key> as described here to have the operating system restart Maestral automatically whenever it crashes. My “technique” requires manual intervention to get things going again, but it’s more flexible (and it can’t cause crash loops): You could, for instance, use a variant of it to receive a notification when a long-running process finishes.