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.

2
  • 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 shellcheck.net Commented Oct 17, 2016 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?. Commented Oct 18, 2016 at 1:47

2 Answers 2

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)

Sign up to request clarification or add additional context in comments.

3 Comments

Wow it works now, probably the environment variable is the key. But, launchctl list|stop|start are not working, any idea why?
Hey mate, I'll have a look
If I could start and stop the service that would have been great, still great job. This helped me a lot!.
3

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.)

1 Comment

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.