Search code examples
rubymacosnotificationsosx-mountain-lionlaunchd

Failure to run terminal-notifier (Ruby app) from a Launch Agent in OSX. Environment variable problems?


I'd like to periodically pop up a notification (I have a "current task" I'd like to display, in a Pomodoro style app). I am attempting to use a user Launch Agent to schedule the task, which works successfully for running .sh or .py scripts. However, I'm not able to schedule the terminal-notifier to successfully launches. A possible cause from other reading is that the Environment variables are different for the Launch Agent process than the usual logged in user's Environment.

I install terminal-notifier via gem install terminal-notifier

myusername@Nathans-MacBook-Pro~/bin$ which terminal-notifier 
/Users/myusername/.rvm/gems/ruby-2.0.0-p0/bin/terminal-notifier

Here's my shell script reminder.sh:

#!/bin/sh
date >>/tmp/reminder.log
terminal-notifier -message "message txt" -title "title txt"

Running this script directly from the Terminal works as expected: a time-stamp is logged in reminder.log and the notification pop-up appears. However, when I try to run it via launch-agent it fails.

I put in ~/Library/LaunchAgents/ a file com.myusername.Reminder.plist with the following contents.

<?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.myusername.Reminder</string>
    <key>Program</key>
    <string>/Users/myusername/bin/reminder.sh</string>
    <key>RunAtLoad</key>
    <true/>
    <key>StartInterval</key>
    <integer>10</integer>
</dict>
</plist>

After creating this file I then load it

launchctl load ~/Library/LaunchAgents/com.myusername.Reminder.plist

and (not sure if needed, as it includes RunAtLoad)

launchctl start com.myusername.Reminder

While it successfully logs a timestamp to the file every 10 seconds, it doesn't trigger a notification.

Any tips on how to make this successfully run?

Thanks!


Solution

  • Your assumption is right. launchd(8) has no idea where to find terminal-notifier. The simple solution is to call terminal-notifier with an absolute path. Adjust your shell script like this:

    #!/bin/sh
    date >>/tmp/reminder.log
    /Users/myusername/.rvm/gems/ruby-2.0.0-p0/bin/terminal-notifier -message "message txt" -title "title txt"
    

    Alternatively you can always extend the PATH environment variable using the launchd(8) key EnvironmentVariables. The corresponding section in your job definition should look like this:

    <key>EnvironmentVariables</key>
    <dict>
        <key>PATH</key>
        <string>/usr/bin:/bin:/usr/sbin:/sbin:/Users/myusername/.rvm/gems/ruby-2.0.0-p0/bin</string>
    </dict>