MacOS – Using launchd to monitor a running program or process

bashlaunchdmacos

I've written a simple bash script to check whether a program (supplied as its only argument) is running and send an email to a set address in the script if it's not. The script works if run on the command line, but I cannot for the life of me get it to work under launchd as a user agent (~/Library/LaunchAgents) where I try to set it to run every minute. The latest incarnation of the relevant .plist file is (monitoring Dropbox):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!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>greencollar.Dropbox.checkRun</string>
        <key>StartInterval</key>
        <integer>60</integer>
        <key>Program</key>
        <string>/Users/greencollar/Documents/code/proc_check.sh</string>
        <key>ProgramArguments</key>
        <array>
            <string>proc_check.sh</string>
            <string>Dropbox</string>
        </array>
    </dict>
</plist>

Yes – the bash script is executable and no there are no entries in Console indicating any problems with the .plist file. I have tried making /bin/bash the program, but that doesn't seem to make any difference and reading execvp(3) seems to hint that it wouldn't. I've also tried having everything under <ProgramArguments> without any luck as well. Any help would be greatly appreciated as this seems to me pretty basic and it's very frustrating that I can't get it to work!

—————————– 1st Edit —————————

Here is the pared-down basics of the shell script:

#!/bin/bash
PROC=$1
if ! /usr/bin/pgrep $PROC > /dev/null
then
    /bin/echo "$PROC is not running!" | /usr/bin/mail -s "$PROC down" email@mydomain
fi

Not much to go wrong there…

Best Answer

I'm posting this as an answer because it's to much for a comment and I believe I know what the issue may be, even without seeing the contents of the proc_check.sh shell script.

I realized after reading again your question and ensuing comments, after deleting my first answer, the hint was the script worked from the command line but not when called by launchd.

When your User Agent .plist file is triggered, the $PATH it receives may not contain the paths to some commands/utilities that are being called within the script. The $PATH passed to the proc_check.sh shell script is only:

/usr/bin:/bin:/usr/sbin:/sbin

So, any program that is called in the script that is not in the above $PATH or includes it's fully qualified pathname is not running when called by launchd.

To fix this, either use the fully qualified pathname for all executables called within the script, that are not in the above $PATH, or add a PATH=... statement after the shebang, where ... is the actual output of, echo $PATH in Terminal, e.g.:

#!/bin/bash
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin

Note: The $PATH above is what's outputted by echo $PATH on my system and may well be different on yours.