0

I have written a bash script to continuously checks a service. The script has some functions and also calls other source bash files and works fine when executed manually. The script has a continuous loop statement something like,

while true; do
{

$path/is_it_running
if [ "$?" == "0" ]; then
{
echo "yes, it is running"
$path/test
if [ "$?" != "0" ]; then
fix_the_issues
fi
}

else 
echo "It is not running!"

fi
sleep 10
}
done

/Library/LaunchDaemons/my.own.service.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>my.own.service</string>
        <key>ProgramArguments</key>
        <array>
            <string>/bin/bash</string>
            <string>/path/to/bash/script</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
         <key>KeepAlive</key>
        <true/>
        <key>StandardOutPath</key>
        <string>/var/log/my-service.log</string>
    </dict>
</plist>

sudo launchctl load -w /Library/LaunchDaemons/my.own.service.plist

/var/log/system.log:

com.apple.xpc.launchd[1] (com.apple.quicklook[80608]): Endpoint has been activated through legacy launch(3) APIs. Please switch to XPC or bootstrap_check_in(): com.apple.quicklook

The issue what i'm facing: The script is not running exactly how it runs when manually executed. I can say launchd triggers the script as I could see "yes, it is running" and "It is not running!" messages from the plist StandardOutPath log file /var/log/my-service.log.

Can anyone help me here to successfully run the bash script as service?. It looks difficult for me in osx unlike debian/centos. BTW, it's osx EI Captain and Sierra editions.

user465465
  • 441
  • 3
  • 13
  • 26
  • Try putting a proper shebang at the start of your script `#!/bin/bash` and removing `bash` from your arguments array. Also, try indenting your shell script to make it legible and run it through http://shellcheck.net – Mark Setchell Oct 17 '16 at 19:34
  • The script file has `#!/bin/bash` at the top and in all other source file which it calls. I can remove in plist arguments. it echoes if it is running or not running perfectly, but not doing certain action when the service is running or not running. I have been testing this script file and it works exactly how I wanted. It uses `sudo` somewhere which prompt for password, I don't think launchd waits for this to be answered as it runs as root, do you?. – user465465 Oct 18 '16 at 01:47

2 Answers2

3

The following works for me for a bash script on OSX 10.10:

<?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>Disabled</key>
    <false/>
    <key>EnvironmentVariables</key>
    <dict>
        <key>PATH</key>
        <string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/sbin</string>
    </dict>
    <key>KeepAlive</key>
    <dict>
         <key>SuccessfulExit</key>
         <false/>
     </dict>
    <key>Label</key>
    <string>SomeNameHere</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/bash</string>
        <string>/path/to/bash/script</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

I used Lingon to create it. You could use the free trial for it as well to solve your current issue.

You would need to use version 4:

Requires macOS 10.11 or later (works perfectly with macOS 10.12 Sierra)

Ashutosh Jindal
  • 18,501
  • 4
  • 62
  • 91
2

This is a stylistic fix for the bash antipatterns in your script. I would post it as a comment but comments cannot contain code formatting.

while true; do
#{  no braces necessary here
# note indentation
    # Don't examine $? -- if already does that for you
    if $path/is_it_running; then
    #{ no braces necessary here
    # note indentation
        echo "yes, it is running"
        # Don't examine $? -- if already does that for you
        if $path/test; then
            fix_the_issues
        fi

    #}  No braces necessary       
    else 
        # Note indentation
        echo "It is not running!"
    fi
    sleep 10
#} No braces necessarsy
done

You might also want to visit http://shellcheck.net/ for an automated review of your scripts. (Though it doesn't examine indentation, which is purely for human legibility.)

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • 2
    This came up in a review queue for deletion which I find a little bizarre. I'm considering it an XY answer. It looks like a helpful attempt to address OP problems they weren't aware of. Hardly unusual. – zzxyz Sep 28 '18 at 18:50