Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

Use launchd to replace folder actions System
Folder actions are quite slow, and on 10.5.x, I found them to be not really fun to play with. Another way to watch a folder is to create your own launchd script. Here's one as an example:
<?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>Label</key>
    <string>com.domain.whatever</string>
    <key>ProgramArguments</key>
    <array>
        <string>/Library/Scripts/domain/whatever.sh</string>
    </array>
    <key>QueueDirectories</key>
    <array>
        <string>/Volumes/hd/any/path/to/a/folder</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>onDemand</key>
    <true/>
</dict>
</plist>
In the above, whatever.sh calls an AppleScript that automatically does something with newly arrived files (OCR, picture conversion, etc.):
#!/bin/bash
osascript /Library/Scripts/domain/whatever.scpt
This works fine, but you may find entries like this in you logs, repeated every 10 seconds:
01.04.08 10:54:17 com.apple.launchd[146] (com.domain.whatever) Throttling respawn: Will start in 9 seconds
01.04.08 10:54:28 com.apple.launchd[146] (com.domain.whatever) Throttling respawn: Will start in 8 seconds
01.04.08 10:54:38 com.apple.launchd[146] (com.domain.whatever) Throttling respawn: Will start in 9 seconds
In my case, I took the new files to OCR, saved them as PDFs, and removed the files after processing. But still, launchd started and stopped every 10 seconds. But why? The answer is quite easy: the Finder placed an invisible .DS_Store in that folder. My AppleScript did not remove it, but launchd was aware of that "new" file, and restarted endlessly. Fix: remove the .DS_Store as last action of your AppleScript:
set DeleteMe to alias "hd:any:path:to:a:folder:.DS_Store"
set rmMe to POSIX path of DeleteMe
try
    do shell script "rm " & quoted form of (rmMe)
end try
With this fix, launchd will stop restarting. There might be other ways to get rid off these .DS_Store's, but this was the easiest fix for me.
    •    
  • Currently 1.89 / 5
  You rated: 2 / 5 (9 votes cast)
 
[21,346 views]  

Use launchd to replace folder actions | 13 comments | Create New Account
Click here to return to the 'Use launchd to replace folder actions' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Use launchd to replace folder actions
Authored by: mjb on Apr 23, '08 02:01:13PM
Why not just add the deletion if the .DS_Store file to the end of the shell script launchd calls? Something like:

#!/bin/sh

osascript /path/to/applescript.scpt

DSSTORE='/path/to/a/folder/.DS_Store'
if [ -f $DSSTORE ];then
   rm $DSSTORE
fi


[ Reply to This | # ]
Use launchd to replace folder actions
Authored by: squawbrah on Apr 23, '08 05:44:11PM
Nice hint. I discovered two things when I tried it out:

1) You should probably use WatchPaths instead of QueueDirectories to prevent an endless loop and also (I think) eliminate the problem with .DS_Store files.

When I tried a simple folder action--making a file's label turn red when put in the target folder--with QueueDirectories, my CPU use jacked way up and never came down. Using WatchPaths instead solved the problem.

2) You can call an AppleScript directly--instead of having a shell script call an AppleScript--by putting this in your .plist file:

<key>Program</key>
<string>/usr/bin/osascript</string>
<key>ProgramArguments</key>
<array>
<string>osascript</string>
<string>/Users/foo/path/to/myscript.scpt</string>
</array>

Lots more info at http://www.afp548.com/article.php?story=20050620071558293

--Thanks



[ Reply to This | # ]
How do you use this?
Authored by: MacTipper on Apr 23, '08 02:10:43PM

Can somebody please elaborate on how one would apply this to LaunchD?

Thanks in Advance,
MacTipper

---
MacTipper
Check out my mac tip blog



[ Reply to This | # ]
How do you use this?
Authored by: regulus on Apr 23, '08 03:14:38PM

Notice how you set a name in the part "com.domain.whatever". So what you do is save that text file with the name and a ".plist" extension i.e. com.domain.whatever.plist. Then you take that file and put it in your ~/Library/LaunchAgents folder. The next time you logout or reboot your computer launchd will see the file and it will be working.



[ Reply to This | # ]
How do you use this?
Authored by: mjb on Apr 23, '08 05:46:20PM
I imagine you could force the load immediately without a reboot/relogin with launchctl? Perhaps:

$ launchctl load ~/Library/LaunchAgents/com.domain.whatever.plist
(Not a launchd/launchctl guru here, please correct as needed)

[ Reply to This | # ]
How do you use this?
Authored by: mmnw on Apr 24, '08 02:36:18AM
This is perfectly correct. I'd like to add, if you would like to remove the job, you use
launchctl unload ~/Library/LaunchAgents/com.domain.whatever.plist
If you would like to remove the job permanently you should also delete/move the file from that folder (or set the disabled key in the plist file to true, see the man launchd.plist for details). You should also unload and then load again if you modify the .plist file.

[ Reply to This | # ]
How do you use this?
Authored by: Peter_T on Apr 24, '08 12:51:45AM
The best launchd description / tutorial I've found is at afp548 [link:]http://www.afp548.com/article.php?story=2008030421090192

[ Reply to This | # ]
How do you use this?
Authored by: MacTipper on Apr 24, '08 08:38:53AM

Thanks for the help everybody!

MacTipper



[ Reply to This | # ]
Use launchd to replace folder actions
Authored by: Zeitkind on Apr 24, '08 05:35:32AM

I tried both WatchPaths and QueueDirectories, but still looking for some more detailed info except looking into the source code of launchd. I used it to handle tiffs incoming from a network scanner to a server volume, pass them to Readiris, ocr them and save in another dir as PDF - Acrobat Pro is better scriptable, but the PDFs are not searchable by Spotlight (Acrobat's OCR is a crap, it makes "word" to "w o r d" and Spotlight won't find any word but "w o r d" and - Readiris can ocr much more languages). I tried first with folder actions, but found them unstable and much slower. The reason I splitted into a shell-script and an Applescript is that it leaves the possibility to do more things first with the shell - which is much faster than any AppleScript - like converting images or splitting tiffs. Readiris Pro is a pita to script, I needed System Events to control it, but sure you can get their "corporate edition", which might be better scriptable, no idea but I think so.



[ Reply to This | # ]
Use launchd to replace folder actions
Authored by: TheCrunge on Apr 24, '08 07:09:41AM
The biggest problem I've found with using launch daemons is that you can't pass the name of the added item. Using folder actions, you can get the name and the path of each item added. For example:
on adding folder items to this_folder after receiving added_items
         repeat with the_item in added_items
                   set the_posix to POSIX path of the the_item
                   display dialog "The added item is " & the_item & " and is located at " & the_posix
         end repeat
end adding folder items to
Using launch daemons, there is no argument passed to your script providing the name or the path of the item. It makes it difficult to manipulate this new file without knowing it's name or path. Am I wrong?

[ Reply to This | # ]
Use launchd to replace folder actions
Authored by: Zeitkind on Apr 24, '08 01:16:29PM

It simply depends on your needs. In my case, I know that there will be one to many tiff-files which need to be ocr'ed. It's very simple to get a list of files with AppleScript:
tell application "Finder"
set myFolder to alias "Volumename:path:to:folder:"
set myList to every file of myFolder as alias list
end tell
You then have an array with all the files as alias. With a repeat or while or whatever kind of loop you can process the files.



[ Reply to This | # ]
Use launchd to replace folder actions
Authored by: ceesaxp on May 02, '08 10:23:51PM
Well, I suppose (have not tried) that launchd when calling whatever.sh would be passing it each item one-by-one (i.e. calling it several times if multiple items were added). In case of /bin/sh they will be known to shell script as $1, and then will be passed over to AppleScript. So, you should have all the same (or similar) info and control, no?

[ Reply to This | # ]
Use launchd to replace folder actions
Authored by: sderman on Apr 25, '08 01:11:02PM

Note, if you use QueueDirectories, then you must empty the directory.

If you use WatchPaths instead, then launchd will fire when a file changes in the directory:
<key>WatchPaths</key>
<array>
<string><path to some dir></string>
</array>



[ Reply to This | # ]