Skip navigation

launchd disobeying plist

2315 Views 34 Replies Latest reply: May 7, 2012 6:36 PM by Jonathan Pool RSS
1 2 3 Previous Next
Jonathan Pool Level 1 Level 1 (40 points)
Currently Being Moderated
May 6, 2012 4:10 AM

I am using launchd to execute a shell script whenever any of a set of directories is modified and also when a filesystem is mounted.

 

The script should not run when it is loaded. It should also run only once whenever a condition for its running is satisfied.

 

According to my reading of the the man page for launchd.plist, I should be able to make this work with a plist that contains only Label, Program, QueueDirectories, and StartOnMount parameters.

 

However, in fact the script gets executed when I load the /Library/LaunchAgents directory, and it continues to do this even if I insert a false-valued RunAtLoad key into the plist. So launchd appears to be disobeying the default value of RunAtLoad and also an explicit false value of that key.

 

Also, once it runs the script is respawned continuously. And this happens even if I add a false-valued KeepAlive key into the plist. So launchd appears to be disobeying the default value of KeepAlive and also an explicit false value of that key.

 

Moreover, if I specify the script's pathname as the value of a Program key, I get an "Exec format error" message. To make the script run, I need to specify it as the only value of a ProgramArguments key. By my reading these should be equivalent. So launchd appears to be disobeying the value of a Program key.

 

When the script runs, it runs correctly, and, if launchd is queried about it while it is being respawned, launchd reports that its last exit status was 0.

 

Here is a plist that seems to at least function, though it runs on load when it should not. I'd like to know why launchd is behaving in all these ways that seem to contradict the man page.

 

<?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>RunAtLoad</key>

          <false/>

          <key>ProgramArguments</key>

          <array>

                    <string>/Users/Shared/Library/panlex/org.panlex.syncd.txt</string>

          </array>

          <key>LaunchOnlyOnce</key>

          <true/>

          <key>ThrottleInterval</key>

          <integer>36000</integer>

          <key>KeepAlive</key>

          <false/>

          <key>QueueDirectories</key>

          <array>

                    <string>/Topics/panlex/panlex-dics/panlex-dics-data/panlex-dics-data-todo/queued</string>

                    <string>/Topics/panlex/panlex-dics/panlex-dics-data/used</string>

          </array>

          <key>StartOnMount</key>

          <true/>

          <key>Label</key>

          <string>org.panlex.syncd.txt</string>

</dict>

</plist>

Mac Pro, Mac OS X (10.5.7), iPhone 8GB, Airport Extreme
  • etresoft Level 7 Level 7 (23,905 points)
    Currently Being Moderated
    May 6, 2012 8:32 PM (in response to Jonathan Pool)

    org.panlex.syncd.txt sure does not look like a valid script.

     

    I suggest reviewing you parameters. The LaunchOnlyOnce parameter doesn't look appropriate. If you are using the same value as a default setting, then get rid of it. Avoid adding both QueueDirectories and StartOnMount until you are sure one is doing what you want the way you want.

  • Linc Davis Level 10 Level 10 (107,830 points)
    Currently Being Moderated
    May 6, 2012 9:39 PM (in response to Jonathan Pool)

    Remove the RunAtLoad, LaunchOnlyOnce, and KeepAlive keys.

  • twtwtw Level 5 Level 5 (4,580 points)
    Currently Being Moderated
    May 6, 2012 11:20 PM (in response to Jonathan Pool)

    KeepAlive set to false does not mean what you think it means - it tells launchd to restart the process immediately if the process returns with an error.  Since you keep getting an exec format error, launchd keeps trying to restart the process.

     

    QueueDirectories are tricky to use.  more on that later if need be.

     

    I'm not sure how wise it is to give a unix script a .txt extension.  The system expects that a .txt file is a data file, not an executable.  That's probably why you're getting an error in the first place.

     

    LaunchOnlyOnce is only supposed to be used when it's critical that a process only run once.  It's better to handle that in the script using conditionals.

     

    it would be helpful to know what your script is trying to do - that might narrow down the problem.

  • twtwtw Level 5 Level 5 (4,580 points)
    Currently Being Moderated
    May 7, 2012 12:31 AM (in response to Jonathan Pool)

    launchd works fine - it's integral to the system (even cron is launchd-based in OS X, so don't think you're getting away from it).  There's just something in your script or plist that's out of kilter.  I suspect this is an rsync issue; rsync uses multiple sub-processes, and launchd can handle sub-process ungracefully (in order to avoid zombie processes) unless you set the AbandonProcessGroup key to true.

     

    From what you've said, I can tell part of why your script isn't working.  QueueDirectories is unsuited to rsync; QD requires that the watched folder be emptied completely before it will trigger again.  you'd really want to use the WatchPaths key instead (which would trigger with every change to the folder), except that an rsync run probably takes longer than the average change period of the folder (unless it's a really dead folder), meaning that rsync would be constantly running on your machine. 

     

    If I were you, I'd forget about the StartOnMount and QueueDirectories trigger, and just run a periodic sync using StartInterval or StartCalendarInterval.  It would make your life much easier.

  • Linc Davis Level 10 Level 10 (107,830 points)
    Currently Being Moderated
    May 7, 2012 7:35 AM (in response to Jonathan Pool)

    Try adding the AbandonProcessGroup key (value true.)

  • twtwtw Level 5 Level 5 (4,580 points)
    Currently Being Moderated
    May 7, 2012 8:21 AM (in response to Jonathan Pool)

    <sigh> QueueDirectories works as documented; i isn't intended for what you're doing.

  • twtwtw Level 5 Level 5 (4,580 points)
    Currently Being Moderated
    May 7, 2012 8:38 AM (in response to Jonathan Pool)

    You haven't shown us your script, so anything I say is only a best guess based on general information. If you want definitive, give more information.  And what you quoted about QueueDirectories says explicitly that the job will only launch if the directory is empty.  Ipso facto, if something is added to the directory, it must be removed before the trigger will fire again.  Man pages are not intended to be Ikea-style constrution manuals.

     

    How you solve your problem is your business, and I'm happy to help whichever you choose.  If cron works for you and you want to use it, great. However, I'm getting annoyed because you seem set on spreading misinformation rather than figuring out where you goofed up.  launchd works fine - if it didn't your computer wouldn't boot - so please stop blaming the system for mistakes you don't realize you're making.  Either ask for some honest help, or give it up and use cron.

1 2 3 Previous Next

Actions

More Like This

  • Retrieving data ...

Bookmarked By (0)

Legend

  • This solved my question - 10 points
  • This helped me - 5 points
This site contains user submitted content, comments and opinions and is for informational purposes only. Apple disclaims any and all liability for the acts, omissions and conduct of any third parties in connection with or related to your use of the site. All postings and use of the content on this site are subject to the Apple Support Communities Terms of Use.