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:
sleep 11
– launchd needs a min. of 10 seconds of program execution time by default. I just put this in here to accommodate launchdecho "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./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:
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 theroot
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.