Mac GeekeryGet your geek on. |
|
blog advertising is good for you
recent popular content
User login
|
If you want to make a program start at a certain time, for a certain event, or just stay running, the new [Plug: There is now a program to edit launchd property list files in a GUI rather than manually-creating the text: Launchd Editor] launchd replaces a good many parts of Mac OS X in Tiger. Specifically, it absorbs the functionality of: With all of this power behind it, launchd looks pretty useful, but it goes further adding:
Start your FTP daemon only when needed, and confine it to one part of the OS. Start your SMTP sending daemon only when there’s a queue. Start your Automator workflow as soon as a folder has a file in it. Change your computer’s settings whenever a preference file is updated. The possibilities are almost limitless. But I’m not here to say what you can do with this (yet). I’m here to show you how to get started. Property lists are the format of choice in Mac OS X, and launchd is no different. Using Property List editor, create a new list and add the following items:
Set them as follows:
Save this file in launchctl load Library/LaunchAgents/com.apple.TextEdit.plist TextEdit should start right up. Do not quit it for ten seconds. Wait about 15, then quit it. Notice it start up again. Now run: launchctl unload Library/LaunchAgents/com.apple.TextEdit.plist Watch TextEdit go away. Congratulations, you’ve made a launchd item. Now for some fun. Run: touch /tmp/start_te Open the property list up in Property List Editor again and change OnDemand to true. Now add an array WatchPaths and add the string Can you see what fun this could be? No? Let’s have some more. Remove Rename the touch /tmp/te/te Wait a few seconds and try and quit TextEdit. Won’t stay dead, right? Remove the As you can probably see by now, this has incredibly useful implications for even the average user. The great part is that There are more options in the manpage for the launchd.plist files so you can see other ways to get things started as well. It’s really quite fun when you get down to it, so have at it. As of 10.4.0, calendar-date-based events do not appear to work more than once per load. A bug has been filed. 1 Mostly. 2 It can, but it’s not implemented as such right now.
About Adam Knight
Author Biography Adam Knight is one of the founders of Mac Geekery and is a geek at heart. Programmer by day, hacker by night, his daily life revolves around the Macintosh platform, which he has been a user and programmer for since the early days of System 7 when his LCII replaced his Apple //c. In-between tech jobs, he’s managed to learn the basics of any web hacker: PHP, MySQL, Perl, Apache, Linux, *BSD, and the intricacies of ./configure —prefix=~/bombshelter/. Today, codepoet is concentrating on blogging again, writing some software for the Mac by himself (including Notae) and for his company (such as Switchblade) and has a few other toys coming out soon. Bug him over AIM or email [link fixed]. |
Thanks for the launchd teaser. And for creating this cool site, btw, which has rekindled my interest in Drupal.
“As of 10.4.0, calendar-date-based events do not appear to work more than once per load. A bug has been filed.”
Geez… you’d think when replacing cron, if there’s one thing you’re going to get right, it be date based events! Either way, very cool intro, thanks!
Unless I’m missing something, the treatment of calendar based events in launchd (once working) isn’t much of a replacement for cron. The launchd.plist manpage indicates that StartCalendarInterval is a dictionary of integers (Minute, Hour, Day, etc.) where “The semantics are much like crontab(5)”. Well in a crontab, these parameters are not just integers. Any idea how to do the equivalent of this cron command:
50 8-20/2 * * * root chmod -R 775 /Users/Shared/*
i.e. run said command every two hours each day from 8:50am to 8:50pm
?
I noticed that as well. It doesn’t seem to support both intervals and time periods, but it is a 1.0 version. I’m sure that they’ll support that later on.
Of course, the source code is ridiculously simple so any Joe programmer could add that in and submit it as well.
—
cp
Inetd and xinetd allows you to control access to services based on the source IP address, can the same be done through launchd?
It does not appear launchd has a provision for this, but my presumption is that they want you to use the firewall for such things. Makes more sense, really.
—
cp
It looks like through Tiger Apple has implemented the “service” command on the command line. I’ve used this with Linux and BSD where you can enable or disable services on the system. It says it’s a script.
at the command prompt type:
service —list
It also appears xinetd still runs as a process, and Apple has created an xinet.d directory in /private/etc where configuration files for the services reside.
If you do a more on the “service” script you’ll see a function for restarting xinet.
you can use the service command like this:
sudo service telnet start
and if you do that you can do:
cat /private/etc/xinet.d/telnet
and you’ll see it did this:
service telnet
{ disable = no socket_type = stream wait = no user = root server = /usr/libexec/telnetd groups = yes flags = REUSE
}
If you stop it the “disable” will become “yes”
If you upgraded from Panther then you’ll find a bunch of xinetd configuration scripts in /etc/xinetd.d/ but if you performed a clean installation, the directory will be empty. Tiger on a clean installation will use launchd to launch services while on an upgraded system, it will use xinetd. And the “service” script adapts itself accordingly. On my system (a clean install) - after I ran:
sudo service telnet start
There was no file called /etc/xinetd.d/telnet, but when I ran:
sudo launchctl list
The com.apple.telnetd daemon was running.
Now that’s just kick-ass.
—
cp
Could you elaborate on the OnDemand key listed in the launchd.plist manpage? If I set the StartInterval as 2700 (45 minutes) and OnDemand as true, will the job run every 45 minutes constantly? Or must I set OnDemand to false?
It should be set to true. OnDemand basically means “Do I start this now and keep it running, or wait for a condition?”
—
cp
adsorption in chromatography adsorption in chromatography,lake highland park high school lake highland park high school,clarks buslines qu clarks buslines qu,baytown sexual assault texas baytown sexual assault texas,clarks ebay clarks ebay,victorias sec victorias sec,silo course highland recreation area mi silo course highland recreation area mi,the daily cartoonist the daily cartoonist,highland county ohio jail highland county ohio jail,baytown trails baytown trails,directory of textile importers in france directory of textile importers in france,the one hundred and one dalmatians book characters the one hundred and one dalmatians book characters,rockhouse negril jamaica rockhouse negril jamaica,riverhead mental health riverhead mental health,fleetwood mac landslide guitar tab fleetwood mac landslide guitar tab,l233 l233,skate park baytown skate park baytown,atlantis marine aquarium riverhead ny atlantis marine aquarium riverhead ny,nobilis the secrets of the da vinci code walk through nobilis the secrets of the da vinci code walk through,english highland cattle english highland cattle,
For those interested there’s a Q&A session on IRC tomorrow evening with Dave Zarzycki – the author of launchd – details as posted by Dave:
Date: 5/25/2005
Time: 4pm PDT till when I go to bed
Channel: #launchd
Network: irc.freenode.net
Why am I doing this?
I’ve been tasked to write a HOWTO/FAQ for launchd.
Now, as the guy who wrote launchd, I’m the best and worst person to write such a document.
That’s why I need your help. Feel free to come and hang out and I’ll try and answer as many questions as I can.
See ya then,
davez
Any chance it’s available anywhere yet?
… but I’m not really that much of a geek that I know how to use the Property Editor…!
How do I actually add the instructions (with or without the preceeding bullets?);
Label string
ProgramArguments array
OnDemand boolean
etc…?
Are they typed in or are some bits selected from options?
All help gratefully received.
Eeyore
My House
You’re in luck, I just completed an editor for these lists.
Launchd Editor
—
cp
Nice intro, but does anyone have snmpd running via launchd?
So far, I haven’t been successful..
Make sure you’re using the -f option to not fork it, and use the “maintain” recipe in the Launchd Recipes article. You cannot use the sockets form with that program as it doesn’t even work with inetd.
—
cp
Please excuse any weird formatting and missing greater than/less than and forward-slash symbols from this mail, but I have not yet figured out a way to make them appear… Please assume that all the bits like key and array and string are there and correct
I have this as /Library/LaunchDaemons/Fetchmail.plist
but, at launch, it does this (from /var/log/system.log):
Jun 21 03:42:08 pmac-g5 launchd: FetchmailFromDemon: exited with exit code: 5
Jun 21 03:42:08 pmac-g5 launchd: FetchmailFromDemon: 9 more failures without living at least 60 seconds will cause job removal
here is the fetchmailrc:
set daemon 120
poll pop3.demon.co.uk proto pop3
aka demon.net
aka mailstore
no dns
localdomains xxxxxxx.xxxxxx.co.uk xxxxxxxxxx.demon.co.uk localhost: user “xxxxxxxxxx” pass “xxxxxxxx” to * here
fetchall
preconnect ’echo
date– Connecting’postconnect ’echo
date– Disconnected’Any ideas why this won’t work? I understand that this might not work for on-demand running by launchd as it turns itself into a daemon when it is run, but I just want to run it once at load time, and then just leave it as a daemon.
fetchmail runs fine from the command line and used to run fine from a StartupItem.
What the heck is an error code 5 - can’t find any definitions for launchd error codes any where on the ’net.
The fetchmail daemon likely exited with code 5, not launchd. Launchd is upset that fetchmail didn’t live for 60 seconds (as the manpage documents, this is required).
Run a shell script, instead, and put “sleep 60” in before fetchmail runs, then send the result of fetchmail back as the result of the script so that it’s reported in the error log correctly. If you still get error 5, then it’s certainly fetchmail.
—
cp
Yep, quite right. launchd didn’t like the fact that fetchmail immediately becomes a background/daemon process due to the first line of the fetchmailrc. I thought that was only for on-demand daemons/agents, but it would seem not. From man launchctl:
which seems to be what happens with fetchmail.
Now, I run a script called Fetchmail_runner, viz:
which runs:
and that works like a charm!
Thanks, Geoff.
Would it have been better, stylistically as well as to ensure that the process actually runs, to remove the line in the fetchmailrc that makes it run as a demon polling every 2 minutes, and just have launchd run the process every 2 minutes?
Anyone hazard a guess at the preferred solution?
G.
That’s likely the best solution of all.
—
cp
Someone (specifically, Dave Zarzycki, according to Wikipedia) made an oversight in the design or implementation of
launchd. In my opinion it is a very cool piece of software that all geeky Mac users can get a lot out of, but one thing that it does not do well is take the place ofcron. When an agent has theStartIntervalkey in its.plistfile, so that it is run every N seconds, the restriction that it must run for at least 60 seconds simply should not apply. But it does. So runningfetchmailusingStartIntervalinstead of as a polling process doesn’t work, because fetching email typically doesn’t take 60 seconds. Sure, puttingfetchmailinside a shell script and adding asleepbefore/after it solves the 60 second problem, but who can stomach that?Unfortunately, the 60 second problem is not the only one.
fetchmailexits with status 1 when there is no mail, so if you want to runfetchmailperiodically fromlaunchd, you probably want to report 1 as 0 in your script, or elselaunchdwill think bad things are happening when bad things aren’t happening. (Maybe there is afetchmailoption to report “no mail” as a zero exit status?)So…the stylistic argument for running
fetchmailviaStartIntervalis, I think, not the right one. There remains the argument thatlaunchdwill enable us to not keep bunches of daemon processes hanging around unnecessarily. In the case offetchmail, however, this means forking it every N seconds. N, in my case, is quite small, so there would be a lot of forking. I’d much rather forkfetchmailonce and have it sitting in memory, since it doesn’t leak.I hope this makes sense.
Right so if anyone else out there feels like launchd is really what ought to be running
fetchmail, I have either some help or a question for you, depending on how far along you are. If you haven’t gotten it going yet, putting this file in$HOME/Library/LaunchAgents/fetchmail.plistshould be sufficient to causefetchmailto be run by launchd, upon your next login (or sooner?).Now, the question…well, there are a couple of questions. First, when, exactly, does launchd start
fetchmail? When I log in or when the system boots? Second, how can I get it to stopfetchmail—and specifically, how can I get it to stopfetchmailwhen I log out? It leavesfetchmailrunning and even issuing alaunchctl stop fetchmaildoes not kill the process. ARGH!(By the way, does anyone else think it would be cooler if the math questions you had to solve were a little bit harder, like “What is the Galois group of x^5^+6x^2^+^3?”)
white:~/Library/LaunchAgents paul$ launchctl load com.apple.TextEdit.plist
launchctl: unknown subcommand “automount”
com.apple.TextEdit: Invalid argument
Any idea what this is about?
I might if you posted the plist you’re trying to load…
Include it in-between PRE tags for best display.
I had Program Arguments as two words, rather than InterCapped™ which prevented it from running at all. I still see the automount error, but I suspect it’s something it’s inheriting from my login. It doesn’t happen on a different system I tested it on.
Speaking of automount, I suspect this could be used to load the remote disk that holds my iTunes collection (who thinks 30Gb is enough disk space?). I had automount working on Panther but Tiger changed some things I never caught up on.
Anyway, thanks for the tutorial.
If you check the file it mentions you’ll note that error 1103 is BOOTSTRAP_SERVICE_ACTIVE which would indicate either the module is loaded or something is using a resource it needs.
I’d recommend verifying the file is good, first. Open it in Launchd Editor and re-save it to make sure it’s in a valid format and try and load that.
OK, this is too cool. I have been using a shell script to run an ssh tunnel from my wireless boxes to the wired gateway at my house, but I have to remember to re-run it when systems wake from sleep.
Now, I may not have to do that anymore and — wonder of wonders — I may be able to dispense with the shell script. Though it looks like I may have to have some kind of PID file to prevent it from being run more that one.
Here’s what I have: substitute your own gateway system for XXXX (I connect to 3128 because it’s a squid proxy cache).
Perhaps there are more refined controls that can detect and prevent duplication.
But the bottomline is, this is what I have been looking for.
Is there a way to have launchd respond immediately when a service (such as AppleSpell) exceeds a certain threshold of cpu cycles? I am currently trying to monitor when AppleSpell comes into play while the user types text in any Apple text processor application. The unix ps command shows the active services and their cpu rates.
In case there is no way to work the task above, I wish to know how to trigger a shell script at startup using launchd. I assumed it would simply activate all loaded plists within ~/Library/LaunchAgents/ however this does not appear to be the case (unless I’m doing something wrong).