Apple Event: May 7th at 7 am PT

Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

launchd disobeying plist

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

Posted on May 5, 2012 5:28 PM

Reply
34 replies

May 7, 2012 6:19 PM in response to Jonathan Pool

ok, a short bit of testing and I understand why the utility launches immediately. QueueDirectories checks at load whether the directories in question contain anything and triggers the utility if they do. even an invisible .DS_Store file is enough, and it will keep the utility alive until the folder is empty again. that explains the start-at launch problem.


I'm not seeing the cause of the exec error yet. a quick google search tells that this is a non-specific error (e.g., what the interpreter says when it's grumpy about something it hasn't been programmed to expect). a common cause seems to be spurious invisible/whitespace characters at the beginning of the script file.


WatchPaths jobs do not recurse. as I suggested, better to do periodic syncs.

May 7, 2012 6:36 PM in response to twtwtw

Wow. I don't know how anybody would know that QueueDirectories does this. You have made its behavior clear. Thanks very much. Now I suggest that the man entry be changed to describe that behavior. Something like:


-------------------------------


QueueDirectories <array of strings>


This key will make the job start at load if any of the paths is a non-empty directory and will keep the job alive as long as any of the paths is a non-empty directory. (A directory counts as non-empty if it contains an invisible file or contains an empty directory.)


-------------------------------


Thanks much for discovering this.


Message was edited by: Jonathan Pool

launchd disobeying plist

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple ID.