Launchd and starting a job every day - does "StartCalendarInterval" work?

Has anyone been able to get the StartCalendarInterval option to be able to
work with Launchd plist files?
I can get Launchd to work fine if its watching directories for changes etc, but I am unable to get it to launch a script on a regular basis.
I'd like a script to run once per day so I have simply copied the com.periodic-daily.plist file to my own in ~/Library/
LaunchAgents/. It loads successfully and shows in the list when you run
launchctl list, but nothing happens at the specified times. I have it running a
simply script that creates a text file, but it never executes? (nothing is written
to the logs either.)

Any ideas?
Thx,
Jason.

iBook G4, iMac G5, Mac OS X (10.4.3)

Posted on Nov 22, 2005 5:56 AM

Reply
19 replies

Nov 24, 2005 5:54 AM in response to Jun T.

Thanks Jun T. Your tip was exactly the issue. I set the time that I wanted to run the test to 2hrs into the future and now it works fine when specifying Hours in the plist. Maybe if your testing the days or day in week option you've got to have the first run a coupleof "days" in the future - more testing to be done.

Thanks to all those that contributed and helped solved the problem...

Nov 24, 2005 3:18 AM in response to Jason Scott5

Hi all,

BUT - it works if I specify the minutes figure only! If I try to run the very same script with the very same plist file but with the hour it will NOT work.


If I remember correctly, I have experienced the following symptom when I was testing StartCalendarInterval.

If the scheduled time is, say 14:05, and if you run 'launchctl load ..' at 14:00, then it can happen that the job is not executed, at least today; it may (or may not) be executed tomorrow, I guess.

Please try running 'launchctl load ..' at least 1 (or 2?) hours earlier than the scheduled time of the job.

PowerMac G4 Mac OS X (10.4.3)

Nov 22, 2005 4:43 PM in response to AxL

Hi AxL,

Yes, I have read your post which is intersting. In my case however, my iMac is on 24/7 and never sleeps. Not only that but if I check the logs the periodic jobs keep running at the exact times specified in their launchd plist files, so something is weird here...
Could it be that Apple, knowing that the StartCalendarInterval tag is buggy, have hard-coded the working of the periodic job into Launchd???

I have read in a number of mac forums (here included) where people are saying that StartCalendarInterval doesn't work in the early releases but that it was fixed in 10.4.2?

Does this mean the best and easiest way to schedule tasks on a Mac is via iCal alarms (at least they seem to be working every time)!

Jason.

Nov 22, 2005 7:32 PM in response to Jason Scott5

Hi Jason,
Of course AxL is correct about problems related to sleeping but that doesn't apply to you. Launchd was broken before Mac OS X 10.4.3 as you've read. A bug caused the jobs to run only once and not again after that. However as you point out, that has been fixed. As you have observed, the periodic scripts are run. There is nothing special about them; they run like any script would. Just to make sure, I just created and tested one and they still work. It's StartInterval and I believe WatchPaths that aren't working. At least I can't get WatchPaths to work when the path is a file.

You haven't given us any information with which to figure out what's wrong in your case. You know that the periodic scripts run; how is your job different from the periodic ones?

One mistake made by many people that write cron-type scripts for the first time is to assume that the environment of the script is the same as if the script is run in the shell. The PATH in the script's environment is /usr/bin:/bin:/usr/sbin:/sbin, which is minimal. You should change the script to use absolute paths when invoking all executables. The current working directory is the root of the hard drive, '/' and there is no $HOME directory. I recommend that when you get it working, your first experiment should be to dump the environment so you can study it.

You mention logging. Launchd doesn't log anything by default to my knowledge. If you want to log something, you must invoke syslog yourself. You can also output information to a text file, as I did to get the above information about the environment. Again, remember to use absolute paths.
--
Gary
~~~~
It has just been discovered that research causes cancer
in rats.

Nov 22, 2005 9:22 PM in response to Gary Kerbaugh

Thanks for your info Gary. I'll go through your points by numbers below:

1) I can get WatchPaths to work fine, but have only tested it with directories not files. One thing to note is that it will only work for me when OnDemand is set to true.

2) I will attach the actual script I'm running and the plist file when I get home (don't have access at the moment) suffice to say that all the script does is touch a file.

One thing that you mention that I have not done is include the full path to the "touch" program and this may well be the problem.

3) Logging - what I was meaning is that if the launchctl program fails it puts info in the system log, so I always check it just in case.

Thanks for the help, I'll update this thread with further test results later today.

Nov 23, 2005 4:00 AM in response to Jason Scott5

okay, here are the details... Even if I use full pathnames everywhere it makes no difference.

Here's the simple script I'm trying to execute as a test which works fine when I run it manually:

-rwxr-xr-x 1 jason jason 69 Nov 23 19:21 test_script
------------
#! /bin/bash

/usr/bin/touch /Users/jason/var/touch_text.txt
exit 0
------------

Here's the plist file that I have in the ~/Library/LaunchAgents directory (this is just copied from the standard periodic-daily plist with the label, program arguments and time changed):

-------------
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.jaylin.touch-test</string>
<key>LowPriorityIO</key>
<true/>
<key>Nice</key>
<integer>1</integer>
<key>ProgramArguments</key>
<array>
<string>/Users/jason/scripts/test_script</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>19</integer>
<key>Minute</key>
<integer>30</integer>
</dict>
</dict>
</plist>
-------------

Any ideas?

Nov 23, 2005 5:34 AM in response to Gary Kerbaugh

Thanks for your help here Gary, but removing the " " after the #! didn't make any difference either...

I did reboot my machine in case the launchctl load ... statement wasn't working, so that may have thrown all the timings out. Also I've been setting the start time to about 5 minutes ahead each time to test, maybe it only works after a longer interval or after a reboot or after midnight or when its a full-moon.

Nov 23, 2005 5:32 PM in response to Jason Scott5

Hi Jason,
I'd be happy to post it. I didn't before because I did pretty much what you did. I actually had it laying around from a test of the environment. I wanted to see what effect the "UserName" key had on the environment. The shell script itself had been a test of the environment of a LoginHook. I did essentially what you did; I copied one of Apple's property lists and made minor changes. I named the property list org.dyndns.Username.plist and put it in the /System/Library/LaunchDaemons directory. Its permissions are 644 and I didn't even change the owner to root. All that seemed to matter was that root could read it. Here's the property list

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>org.dyndns.Username</string>
<key>ProgramArguments</key>
<array>
<string>/Users/kerbaugh/Library/init/loginwindow/loginhook.sh</string>
</array>
<key>UserName</key>
<string>kerbaugh</string>
<key>StartCalendarInterval</key>
<dict>
<!--<key>Hour</key>-->
<!--<integer>18</integer>-->
<key>Minute</key>
<integer>46</integer>
</dict>
</dict>
</plist>

You might check to see that the line endings on the file are UNIX line endings but I'm not sure that matters in XML. I commented out the hour key but it worked before with it. Obviously, you don't need the UserName key; I just didn't remove it from the test. I know that's not the issue. One thing, don't copy-and-paste mine as the indention is produced with non-breaking spaces which probably will break XML. If you do copy-and-paste, just replace them with regular spaces or tabs.

The script just dumps a few environment variables into a file, much like yours.

#!/bin/bash
touch loginrecord.txt
echo "The new value of \$( pwd ) is: "$( pwd ) >> loginrecord.txt
echo "The value of \$PWD is: "$PWD >> loginrecord.txt
echo "The value of \$UID is: "$UID >> loginrecord.txt
echo "The value of \$HOME is: "$HOME >> loginrecord.txt
echo "The value of \$PATH is: "$PATH >> loginrecord.txt
echo "The value of \$1 is: "$1 >> loginrecord.txt
echo "past first launchctl" >> loginrecord.txt
/bin/launchctl list >> loginrecord.txt

The permissions are 755 and the path is in the property list.

I'm sure you didn't do anything stupid, just subtly wrong and maybe even careless. However, it's hardly obvious to me and I've done this several times. Oh, what's the name of your property list?
--
Gary
~~~~
When a place gets crowded enough to require ID's, social
collapse is not far away. It is time to go elsewhere. The
best thing about space travel is that it made it possible to
go elsewhere.
-- R.A. Heinlein, "Time Enough For Love"

Nov 23, 2005 5:58 PM in response to Gary Kerbaugh

Hi Gary,

I named my property list com.jaylin.touch-test.plist which is a copy of com.apple.periodic-daily.plist.

The only difference that I can see in what you did and what I'm doing is that I'm placing the plist file in the ~/Library/LaunchAgents directory, whereas you've put yours in the /System/Library/LaunchDaemons directory.

Maybe if you're using the StartCalendarInterval tag in the plist it needs to reside in one of the LaunchDaemons directories not LaunchAgents.

I'll try moving mine to /System/Library/LaunchDaemons when I get home and test it tonight.

When I was testing the QueueDirectories and WatchPaths options it worked with the plist in the ~/Library/LaunchAgents directory.

Jason.

Nov 23, 2005 6:38 PM in response to Jason Scott5

Hi Jason,
No, I just put it in my ~/Library/LaunchAgents directory, changed the minutes key to 19 and loaded it. It ran, although at about 20 after. I didn't logout and log back in; I just loaded it with:

launchctl load ~/Library/LaunchAgents/org.dyndns.Username.plist

Invoking launchctl without using sudo puts the job in the user's job list. You might try running "launchctl list" to make sure yours loaded. By the way, with what app did you edit your property list?
--
Gary
~~~~
"Contrariwise," continued Tweedledee, "if it was so, it
might be, and if it were so, it would be; but as it isn't,
it ain't. That's logic!"
-- Lewis Carroll, "Through the Looking Glass"

This thread has been closed by the system or the community team. You may vote for any posts you find helpful, or search the Community for additional answers.

Launchd and starting a job every day - does "StartCalendarInterval" work?

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