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

Another take on reliable daily/weekly/monthly scripts System
I am sort of annoyed that Mac OS X does not reliably run the daily, weekly and monthly scripts if your machine is not 'awake' all night. Here is my solution, with no new installed software packages. This solution uses a script to check the age of the existing log files to determine if the maintenace scripts need to be run again.

STRONG WARNING: this can disable GUI logins if you aren't careful, requiring an SSH login to fix. Done right, there is no problem.

Read the rest of the article for the how-to...

[Editor's note: As with all hints here, what the following may or may not do to your system is completely your responsibility. If you don't know what you're doing in the Terminal, I would not recommend trying this hint. There are easier methods of insuring that the maintenance scripts are run on a regular basis; MacJanitor, for example, is a freeware program which runs the maintenace scripts from the GUI. This is presented here as another method for those that might prefer a more low-level solution.]

First, we'll create a LoginHook script. I chose Perl because I am familiar with it. My script lives in /var/root/AdminScripts/LoginHook, and is as follows:

#!/usr/bin/perl -T

use strict vars;
%ENV = ();

# do daily/weekly/monthly maintenance
my $NOW = time();
my $ONEDAY = 60 * 60 * 24;
my $ONEWEEK = $ONEDAY * 7;
my $ONEMONTH = $ONEDAY * 30;

my $dailyOut = '/var/log/daily.out';
my $weeklyOut = '/var/log/weekly.out';
my $monthlyOut = '/var/log/monthly.out';

# Choose the one(s) that should be run
if (
(!-e $dailyOut)
||
(
(-e $dailyOut)
&&
($NOW - (stat($dailyOut))[9] >= $ONEDAY)
)
) {
system("sh /etc/daily 2>&1 | tee $dailyOut | mail -s "`hostname` daily output" root");
}

if (
(!-e $weeklyOut)
||
(
(-e $weeklyOut)
&&
($NOW - (stat($weeklyOut))[9] >= $ONEWEEK)
)
) {
system("sh /etc/weekly 2>&1 | tee $weeklyOut | mail -s "`hostname` weekly output" root");
}

if (
(!-e $monthlyOut)
||
(
(-e $monthlyOut)
&&
($NOW - (stat($monthlyOut))[9] >= $ONEMONTH)
)
) {
system("sh /etc/monthly 2>&1 | tee $monthlyOut | mail -s "`hostname` monthly output" root");
}
Change the permissions on the file like so:
sudo chmod 750 /var/root/AdminScripts/LoginHook
This looks at the daily, weekly and monthly logs as a way to determine the last-run time for the various scripts. If the file does not exist, or if it is old enough to signify that the script has not been run recently, it will run the scripts in the same form as used in /etc/crontab.

Next, we need to tell loginwindow to run the LoginHook script whenever someone logs in. Note that this isn't necessarily the most efficient place to do this if your machine has people logging in and out all day long, but LoginHook is crafted to only run the various scripts when necessary, no matter how many times it is called.

Edit /etc/ttys to change this:
console "/System/Library/CoreServices/loginwindow.app/loginwindow"[space]
vt100 on secure window=/System/Library/CoreServices/WindowServer[space]
onoption="/usr/libexec/getty std.9600"
to this:
console "/System/Library/CoreServices/loginwindow.app/loginwindow[space]
-LoginHook /private/var/root/AdminScripts/LoginHook" vt100[space]
on secure window=/System/Library/CoreServices/WindowServer[space]
onoption="/usr/libexec/getty std.9600"
Note that these are both one-liners. Linebreaks should be removed, and replace [space] with the actual space character. Make sure to change the path to LoginHook if you put it somewhere else.

Now reboot! There is a big caveat here - if you log in and it seems to hang after you type in your password, there is probably something wrong with the LoginHook script. If you don't want to debug the script, log in via SSH, revert the console line in /etc/ttys to remove the -LoginHook flag, and reboot.

I'm not responsible for damage to your system, your mileage may vary, caveat emptor, etc.
    •    
  • Currently 2.25 / 5
  You rated: 1 / 5 (4 votes cast)
 
[17,985 views]  

Another take on reliable daily/weekly/monthly scripts | 13 comments | Create New Account
Click here to return to the 'Another take on reliable daily/weekly/monthly scripts' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
maybe better to run this from cron
Authored by: hayne on May 04, '02 04:49:37AM

This script seems to do the right thing, but installing it as as a LoginHook wouldn't be very useful for me since I typically stay logged in for weeks at a time on my iBook. I almost never shutdown - I just sleep.

So it occurs to me that this script would be more usefully run as a cron job - say every 15 minutes. That way, the maintenance scripts would run provided only I had the machine awake for at least 15 minutes.
And it avoids any worries about typos accidentally disabling my login.



[ Reply to This | # ]
Just change crontab
Authored by: Anonymous on May 04, '02 09:10:16AM

I guess this hint could be useful for some people.

My take on it (for my desktop machine) was to change the /etc/crontab to run the scripts in the 6 AM hour when the machine is pretty sure to be on and idle. That way I can comfortably shut down the machine when going to sleep at night. (I really don't care for "uptime" geek creds.) I am an early riser and turn it on first thing, so I know it will be on at 6 AM.



[ Reply to This | # ]
I would recommend anacron instead
Authored by: Anonymous on May 04, '02 09:19:08AM

Use Fink to install anacron and let it handle the daily/weekly/monthly scripts instead. Anacron works like cron but understands that computers can be turned off. Install and forget, it will just work.



[ Reply to This | # ]
I would recommend anacron instead
Authored by: monickels on May 04, '02 10:57:32AM

I concur with the choice of anacron. What it does for me--with not configuration--is checks every hour at :15 after to see if the scripts have been run in that calendar day (midnight to midnight, not the last 24 hours). If not, it runs them.

The only side effect of this which may be bothersome is that the scripts are rather processor intensive so if you've got other heavy work going on, it's a bit annoying to wait those five or ten minutes for the scripts to finish, during which time you may get the spinning rainbow disk, particularly if you're in the habit of checking your email first thing in the morning, or worse, when you get home from bars at 2 a.m., two times when you may not have the time or patience to deal with the spinning disk.



[ Reply to This | # ]
I would recommend anacron instead
Authored by: hayne on May 04, '02 11:43:08AM
the scripts are rather processor intensive so if you've got other heavy work going on, it's a bit annoying to wait those five or ten minutes for the scripts to finish
I agree - this is what has inhibited me from doing anything so far about making the scripts run during "normal" hours. So what would be good would be a dialog (could be done with AppleScript) that would ask "Is this a good time?" and allow me to postpone script execution like a snooze button on an alarm clock.

[ Reply to This | # ]
folly
Authored by: mervTormel on May 04, '02 11:19:57PM

two words: in sane



[ Reply to This | # ]
Anacron, MacJanitor
Authored by: CyborgSam on May 05, '02 04:52:49PM

I removed anacron because it was dragging my Mac to its knees every boot. The unpredictable times it ran interferred with using my Mac.

I now run MacJanitor manually. I like this the best because I can run it when I leave the Mac alone for awhile (i.e. to watch some tube...).



[ Reply to This | # ]
I get another computer to wake up my mac...
Authored by: a1291762 on May 05, '02 06:38:30PM

Obviously this is only usefull if you have another computer (on the same network)...

I have an old pentium (that I used before I got my iMac) and it runs FreeBSD (any Unix should be fine, it should also be fine to run Windows). 15 minutes before the Mac is meant to do maintenance, it sends a wake up packet (On the mac, Energy Saver -> Wake on Network Administrative Access) that wakes up the mac.

I used a perl script. I think there's a hint on this site with the script in it.

To make sure my clocks stay in sync, I use timed. I also run NTP on my mac so it gets the "correct" time when I connect to the internet (via modem).



[ Reply to This | # ]
Cronaid package available
Authored by: robg on May 11, '02 10:10:22AM

A program known as <a href="http://www.droolingcat.com/software/cronaid/" target=_blank>cronaid</a> seems to do much of what this script does - checks to see if the maintenance tasks need to run, and runs them if necessary. I have not tried it myself, but it's worth looking into if you're looking for an automated solution.

Like others here, though, I either run these manually (I just do it in the shell), or I leave my Mac on and let it happen automatically. I like knowing when the scripts will run, as they are somewhat resource intensive.

-rob.



[ Reply to This | # ]
CRON not running - help!
Authored by: pooduck on Jun 06, '02 01:54:03PM

Using CronniX, I created a crontab for my user account. The crontab reads as follows:
35 12 * * * perl ftp_update.pl

ftp_update.pl is a perl script that posts an html file to an ftp server. The crontab executes correctly using the "Run Now" function in Cronnix - but fails to run (no fail msg - nothing happens) at the designated time. I've also tried time settings of * * * * * which, as I understand it, should run the perl script every minute continuously. Replacing "perl ftp_update.pl" with "./ftp_update.pl" didn't help.

Is there anything I need to activate or install via Terminal to get this to work? I'm running OS X 10.1.5 with Dev Tools installed.



[ Reply to This | # ]
CRON not running - help!
Authored by: Erik Toh on Jul 03, '02 05:34:41AM

Try entering the full path of the shell script or command.



[ Reply to This | # ]
CRON not running - help!
Authored by: llamakc on Oct 21, '02 11:59:21PM

writing a wrapper for your perl script is also an elegant way. plus you should be redirecting STDERR. make it look like this:

* * * * * /path/to/perl /path/to/script.pl 2>&1

that will do it. be sure to plug in your times though.



[ Reply to This | # ]
Another solution that's much easier
Authored by: klktrk on Oct 21, '02 02:37:19PM

Just go to http://www.theapotek.com/teknotes/tools.php and download XJanitor.pl. Yes, there are a few command line thingies you'll have to type, but all in all it's the least invasive but still simple to set up ways of taking care of this problem I've come across. It's a 1K download for crying out loud, and a few command lines! Beats installing and configuring a bunch of stuff. It's been humming along on my machine for several months. Also, as a bonus, you can just add some lines to the script for it to run other tasks at whatever intervals you choose. AND, it can send you e-mail output of your maintenance tasks (assuming you've set up sendmail correctly).



[ Reply to This | # ]