Skip to content

Instantly share code, notes, and snippets.

@zachselby
Last active October 21, 2021 19:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zachselby/f3104c59e0eb238624d96ae3aa69ccaa to your computer and use it in GitHub Desktop.
Save zachselby/f3104c59e0eb238624d96ae3aa69ccaa to your computer and use it in GitHub Desktop.
Keep Unstable Apps Running on Mac OS with a LaunchAgent and a Configured Interval

Keep Unstable Apps Running on Mac OS with a LaunchAgent and a Configured Interval

Overview

After facing issues with Big Sur on an M1 Mac, the following approach was implemented via launchctl and osascript to ensure an app is restarted if found to not be running.

This particular app was running stable on Catalina, and this approach is a temporary workaround until the root cause can be addressed. YMMV.

AppleScript

Create an applescript that executes your Mac application.

In this case, the application shows a window on startup, so there are additional lines to hide the window after 200ms. The application that is crashing in this example is Barrier keyboard and mouse sharing.

Replace references to barrier with the application that is unstable in your case.

~/Users/YOURUSER/bin/barrier-keepalive.applescript:

tell application "Barrier" to activate
delay 0.1
tell application "Finder" to set visible of process "Barrier" to false

This could easily be replaced with bash script, and the LaunchAgent below modified to call /bin/bash rather than osascript.

launchd LaunchAgent

Leverage the launchd system to setup an interval-based service execution. Again, replace barrier with the necessary values to identify your application. The Label can be a dummy value that makes sense to you.

Update the StartInterval to your desired value, in minutes.

~/Library/LaunchAgents/barrier.keepalive.plist

<?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.barrierapp</string>
    <key>ProgramArguments</key>
    <array>
        <string>osascript</string>
        <string>/Users/YOURUSER/bin/barrier-keepalive/barrier-keepalive.applescript</string>
    </array>
    <key>StartInterval</key>
    <integer>5</integer>
</dict>
</plist>

Activate with launchctl

Once the above script and LaunchAgent are in place, activate the agent in your console:

$ launchctl load ~/Library/LaunchAgents/barrier.keepalive.plist

Validate that the agent started successfully:

$ launchctl list | grep barrier
46215	0	application.barrier.812684.812809
-	0	com.barrierapp

You should see a 0 for the exit code on com.barrierapp. This indicates successful execution. Should you see another error code, get more details with launchctl error <your code>.

For example:

launchctl error 78
78: Function not implemented

Once the agent has been updated to address errors, reload it since the agents could be cached:

$ launchctl unload ~/Library/LaunchAgents/barrier.keepalive.plist
$ launchctl load ~/Library/LaunchAgents/barrier.keepalive.plist
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment