MacOS – Bash Script which calls osascript stops working when run by launchd

applescriptbashlaunchdmacos

I am trying to troubleshoot a problem with a bash script that gets called by launchd. Here's a quick summary

  • Calling the script manually by itself works fine with no errors.
  • Within the bash script it calls an AppleScript that posts a notification That AppleScript works fine.
  • The .plist gets loaded and kicks off at the correct interval and calls the bash script. So that works properly
  • The .plist is called from /Library/LaunchDaemons (so it can run regardless if anyone is logged in or not). This means everything is run as root.

The problem occurs within the bash script which calls an AppleScript to post a notification – it just never happens.

#!/bin/bash
# ------------------------------------------------------------------


sleep 11                           
echo "This is a test" > test.txt   
/usr/bin/osascript /Users/allan/Documents/Scripts/AppleScript/notify.scpt "This is a test" "-Test Test Test" "nosound"

exit 0

That's it. A quick summary of what I am doing:

  1. sleep 11 – launchd needs a min. of 10 seconds of program execution time by default. I just put this in here to accommodate launchd
  2. echo "This is a test" – I just write a simple string to a text file to make sure the bash script is getting called. This file gets created with the expected string; this works.
  3. /usr/bin/osascript /Users......blah blah blah... this fails. This is just a simple AppleScript that takes three arguments (body, title, and sound) to provide a notification.

Running by itself or bash script that calls it, it works:

enter image description here

When the bash script is called from launchd it seems to just not work. Can anyone point me in the right direction? What am I missing?

(OS X 10.11.6)


This is the .plist I am using (yes I know it's set for a 45 second interval…I'm testing)

<?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.user.podcastCleanup</string>
    <key>Program</key>
    <string>/Users/allan/Documents/Scripts/Unix/podcastCleanup.sh</string>
    <key>StartInterval</key>
    <integer>45</integer>
    <key>WorkingDirectory</key>
    <string>/Users/allan/Documents</string>
</dict>
</plist>


Following is the notify.scpt AppleScript that is used to generate the notification.

on run argv

    set Message to item 1 of argv
    set Title to item 2 of argv
    set aud to item 3 of argv
    set STitle to "Terminal"
    set Snd to "Blow.aiff"


    if (aud = "sound") then

        display notification Message with title Title subtitle STitle sound name Snd
    else
        display notification Message with title Title subtitle STitle
    end if

end run

Best Answer

Graphical User Session Required

The error occurs because the commands in your osascript require a graphical user session. AppleScript requires a graphical user session to work.

The launchd job is running as the root user in a non-graphical user session.

Alternative Approach

In these situations, the typical approach is to split daemons in two parts – one computer wide and another within each graphical user session. A pipe or socket is frequently used to communicate.

Even as root user, there are barriers that can not be crossed in macOS.