Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Launchctl minimal working example with Python

I'd like to run a python script every minute using launchd. My plist file looks like this:

<?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.turtle.script.plist</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/bin/python</string>
        <string>/Users/turtle/Desktop/turtle.py</string>
        <string>/Users/turtle/Desktop/data/data.txt</string>
    </array>
    <key>StartInterval</key>
    <integer>60</integer>
</dict>
</plist>

This plist file looks good, as I get the following:

plutil -lint com.turtle.script.plist
com.turtle.script.plist: OK

The script works when I run it from the command line:

/usr/bin/python /Users/turtle/Desktop/turtle.py /Users/turtle/Desktop/data/data.txt

I load this plist via:

   launchctl load -w -F com.turtle.script.plist

I've alse tried:

sudo launchctl load -w -F com.turtle.script.plist

I load this job and the python script should write out a file to disk. However no file is ever produced. I examine the job with:

sudo launchctl list | grep com.turtle.script.plist

The output is:

- 1 com.turtle.script.plist

Can anyone help trouble-shoot the problem?

like image 745
turtle Avatar asked Feb 17 '23 20:02

turtle


1 Answers

It sounds like there's some environment dependence inside the script -- essentially, it assumes something about the environment it's running in that's correct when you run it by hand, but not when launchd runs it. Without knowing anything about the script, it's hard to point at what this might be, but I can suggest a few things to look at:

  • sudo launchctl isn't a more powerful version of launchctl, it does something significantly different. You need to figure out which one you want, and use it.

    When you run launchctl as a normal user (e.g. launchctl load), it interacts with your user instance of launchd to manage Launch Agents -- items that run in your user session, under your user identity.

    When you run launchctl as root (e.g. sudo launchctl load), it interacts with the system instance of launchd to manage Launch Daemons -- items that run in system context, as root.

    You'll have to decide which is appropriate, based on what this script does.

  • Check system.log (you can use the Console utility to view it, or tail -f /var/log/system.log) and see if it includes anything to indicate why the script is failing.

  • Add entries to the launchd .plist to record the script's output, and see if that includes any error messages or other indications of what's going wrong:

    <key>StandardOutPath</key>
    <string>/tmp/turtle.out</string>
    <key>StandardErrorPath</key>
    <string>/tmp/turtle.err</string>
    

    It may help to edit the script to add debugging output, so you can tell more about how it's working (/not working).

  • Does the script depend on having a particular working directory and/or environment variables? If so, add appropriate WorkingDirectory and/or EnvironmentVariables items to the .plist.

like image 120
Gordon Davisson Avatar answered Feb 19 '23 11:02

Gordon Davisson