A Parental Control Scheme to Automatically Shut Down At Bedtime
Revision 1.0.2 Dated 2004 Jul 11
People interested in parental controls should also check out Mac Minder. It will not shut the computer down, but will probably do you what you want, and is much easier to program than what I describe herein. It is available at:
Back when our children liked to go swimming with me at the YMCA, we'd agree how long we wanted to be there, and then I'd take them there that much prior to closing. When it was time to go home, the lifeguards would get them out of the pool and out the door, everybody was happy, and I didn't have to bring a book on Patient Positive Persuasive Parenting or be the big meanie jerking them around. Nowadays, the problem is more likely to be turning the computer off to allow for "downtime" and sleep on school nights. Fortunately, the "cron" daemon and the multi-user security system in the Unix base of Mac OS X can play the role of that lifeguard for me, shutting down the computer when it's time to get ready for bed. It took alot of help, learning Unix and Applescript to get it all working, so I am publishing this web page so that other families may easily benefit.
Five minutes before the "downtime" hour which you set, if your child is logged into the Macintosh, a friendly reminder such as this will appear on the screen:

At the scheduled "downtime", the computer will shut down; the screen will go black and the power will be turned off after about 20 seconds. Your child may restart the computer, but it will shut down again within a minute after your child logs in. This will continue until an "uptime" (generally the next morning) when you have programmed that your child may use the computer again.
Operation depends on who is logged into the computer. You may set different "downtimes" for different child/users. You can even set a downtime for yourself if you need to, although, as administrator, you will be able to undo the scheme if your self-discipline is weak.
This scheme works only on a Macintosh running Mac OS X. Generally, this means something manufactured since 1998 or so, with a G3 or higher processor, and RAM upgraded to a couple hundred MB or more. I believe it should work with Mac OS 10.1, but I've only tested it with "Jaguar" 10.2.2 and 10.2.3.
1. Set Up The Macintosh Accounts
Go the the System Preferences > System > Accounts and create New Users as required so that there at least two users, you and your child. The normal setup is to create a separate user account for each child. In the "Type" column, your account should say "Admin". In all other accounts (generally, all children), this should be blank. If this is incorrect, select the user, click on "Edit User..." and check or uncheck "Allow user to administer this computer" as required. While you are editing your child account(s), note their "Short Name". You will need this later.
The screenshot below shows the proper setup for a computer used by my son Brad.

Set a password for your account which your child cannot guess. (And be careful with the hint, too. Children today are smarter than you think.)
If you find that required buttons are grayed out, you are probably logged in as a non-administrator. You'll have to log out and somehow log in as an administrator.
At this point, you may want to select each child/user in turn and click the Capabilities button. This will show you some things the child can do and not do. The screenshot below shows how it looks when your child has maximum capabilities.

Despite all these capabilities, Brad will still not be able to use the computer past the programmed downtime. Note in particular that it is OK to check "Open all System Preferences", because this allows the child to open them and look at them, but not to change any of the important preferences such as User Capabilities, Startup Disk or Date and Time.
2. Set the Computer's Date and Time, and Startup Disk
While you are in System Preferences, click on Date and Time and make sure that these are set correctly. Also make sure that the Startup Disk is set to Mac OS 10.X.
3. Download and Install Open Firmware Password
This step is probably not necessary for children under the age of 5, but you may as well do it now because our children get smarter faster than we do. (See "Technical Notes and Credits", below to learn why.)
Read about, download, install, and run the free Open Firmware Password application from Apple:
http://docs.info.apple.com/article.html?artnum=120095
Pay particular attention to requirement that your computer may need a Firmware update. Also, when running the appication, note that the password you give it may be the same as the administrator account password on the computer if you want to make it simple to remember, but it need not be. The administrator account on the computer and the Open Firmware passwords are actually separate.
4. Download and Install CronniX
This is a freeware application which we will use in the next step to program the Unix crontabs in the computer using a graphical user interface (GUI). Download it from here:
http://www.koch-schmidt.de/cronnix/
(Of course if you're a real Unix geek you may use a text editor instead of CronniX.)
5. Program the crontab
Copy the following paragraph (without the ending carriage-return line-feed) to your Macintosh clipboard.
/usr/bin/users | /usr/bin/grep -q myChildsShortName && /usr/bin/osascript -e 'tell app "Finder" to activate' -e 'tell app "Finder" to display dialog "This Macintosh will turn itself off in 5 minutes. Please save all documents, quit all applications and shut it down before this happens. (If this Macintosh turns itself off, it will take extra time to check files next time it is restarted)." buttons "Good Night!" default button 1 with icon caution giving up after 60'
Launch CronniX, type cmd-O and then type "root" in the dialog box asking for User Name. Type in your (admininstrator) account password when prompted. If it reports an "Empty Crontab", click OK.
Still in CronniX, make the window as wide as possible. Type cmd-N to create a new crontab "entry", which creates one line in the window. Doubleclick on the "echo Happy New Year" default command for the first entry, delete it, and paste from the clipboard in its place.
Click in the white space at the bottom of the window to get back to the beginning of the long command you just pasted in. Now, doubleclick again on the command, find and overtype the word "myChildsShortName" with your first child's short name which you noted when you were setting up the Macintosh Accounts.
In the "Mday" and "Month" columns, doubleclick and overtype the 1 with a single asterisk *. Leave the Wday as asterisk * also.
In the "Min" column, doubleclick and overtype the 0 with 55.
In the "Hour" column, doubleclick and overtype the hour of your first child's "downtime", by which we mean the time you want the computer to shut down, indicating the hours with a 24-hour clock, minus one hour. (The minus one is because here we are programming a warning which will go off 5 minutes prior to downtime, which is in the prior hour.) Here are some examples:
Downtime |
Hour Entry |
7:00 PM |
18 |
8:00 PM |
19 |
9:00 PM |
20 |
Let's check your work with another screenshot. In the example below, I am setting a user whose short name is "bk" for a 9:00 PM "downtime".

Switch to the application from which you are reading these instructions and copy the following line (without the ending carriage-return line-feed) to your Macintosh clipboard:
/usr/bin/users | /usr/bin/grep -q myChildsShortName && /sbin/shutdown -h +0
Switch back to the CronniX application again. Type cmd-N to create another new crontab entry. Again, doubleclick on the "echo Happy New Year" default command in the second entry, delete it, and paste from the clipboard in its place.
As with with the first entry, in that line you just pasted, find the text myChildsShortName and overtype it with your child's short name which you noted when you were setting up the Macintosh Accounts.
Again, in the "Mday" and "Month" columns, and this time in the "Min" column, doubleclick and overtype the 1 with a single asterisk *. Leave the Wday as asterisk *.
In the "Hour" column, type again type your first child's "downtime" hour as before, but this time do not subtract 1. Follow it with a dash and then the number 23, then a comma, then the number 0, then a dash and then another number. This last number should be one less than your child's "uptime", the earliest hour at which your first child rises and is to be allowed computer access. If you want the computer to stay off until after your child returns from school in the afternoon, you may instead enter a PM time using the 24-hour clock. Here are some examples:
Downtime |
Uptime |
Hour Entry |
7:00 PM |
6:00 AM |
19-23,0-5 |
8:00 PM |
3:00 PM |
20-23,0-14 |
9:00 PM |
7:00 AM |
21-23,0-6 |
(The reason for subtracting one here is that if computer use is allowed beginning at, say, 6:00 AM, it should stay off until 5:59, but any time during hour "6" is OK.)
Here's another screenshot to check how you're doing. The following crontab will shut down the computer on user bk from 9:00 PM and not allow it to run again until 7:00 AM; i.e. last example in the table above. (In order to show the whole hours entry "21-23,0-6", I made the Hour column wider by dragging the separator bar in the heading to the right.)

If you have more than one child/users, select both entries and type cmd-D to duplicate them. In each of these three duplicates which appear, overtype your first child's short name with your second child's short name. Repeat for each child/user. Note that you can set different downtimes and uptimes for each child/user.
Click "Save", enter your administrator password again if required, and then quit CronniX.
In this example, the first crontab entry gives a 5-minute warning before the computer shuts down at downtime, and the second entry keeps the computer shut down between downtime and uptime. Many variations are possible. For example, you can use more entries to program a downtime or uptime which is part of an hour, for example 8:15 PM. You may also allow later downtimes on weekends, holidays and vacation. Click on the Help menu in CronniX to learn how the minute, hour, day, month etc. entries actually work. (For more details, open the Terminal application and type "man 5 crontab".) Finally, you may change the text and button name in the warning dialog by changing the quoted text near the end of the first entry.
6. Testing and Troubleshooting
In a perfect world, your child will always turn the computer off before downtime, but in the real world, your cron program will be called upon to put up the warning and then shut things down at least until the child learns that this is for real. Note that CronniX just writes a file, called the crontab, which is read by the unix "cron" daemon. Unfortunately, the entry and the command it contains must be absolutely perfect in order to work. If you did anything wrong, it will not tell you what you did wrong. Downtime will come and go, and the computer will stay on. Don't be discouraged if it doesn't work at first. I worked on this project on and off for months, but since I figured out all the hard parts, all you should have to do is follow the above instructions exactly. Re-read the instructions and make sure you did everything correctly. Read the Help in CronniX. You may want to troubleshoot it by programming commands to happen immediately.
7. Backing Up The crontab
Unfortunately, all the work you just did with CronniX is saved in the file /private/var/cron/tabs/root. Its directory is a system file which is not backed up when you back up your "Users" folder, and it is not even normally shown in the Finder. Richard Smith contributed the following script to back it up:
cp /private/var/cron/tabs/root "/Users/adminShortName/Documents/crontabBackup" && chown adminShortName "/Users/adminShortName/Documents/crontabBackup"
where adminShortName is your short name. As a homework assignment for further learning in Unix, set this to cron once a day, perhaps just before the shutdown, and the root crontab will be copied into your Documents folder as a file named "crontabBackup" which you will own.
8. Warning: DownTimer Takes No Prisoners
The method described here will shut down if your child your child is logged into it during downtime. Period. This is done not only to give your child the opportunity to sleep but to save electricity. If you have a sophisticated network where users are logging in remotely, this can lead to unexpected results. For example, if you are using a computer with these DownTimer scripts in its crontab, and your child logs in remotely from another computer during downtime, the computer is going to shut down on you. If you want the system to stay running, you could modify the scripts to simply kick your child off instead of shutting down. You may want to put a time delay on the shutdown (use +2 for 2 minutes instead of +0). That way, if you or someone inadvertantly triggers the DownTimer shutdown crontab, you can stop it by quickly opening a Terminal session and killing the "shutdown" process.
9. Feedback
Does it work for you? Click here to send me an email and let me know your ideas. Of course, I'd be really interested if anyone can figure out any loopholes in the scheme which a smart child could "hack" through. I will also try to help with any problems as my time permits.
I wish you and your children pleasant dreams and many good night's sleep!
Jerry Krinock
San Jose, CA USA
Why you must use Mac OS X and not give your child "Admin" capability
The Unix base of Mac OS X protects the system and important files from being modified by any other than the administrator, you. This applies not only to the "crontab" file which you wrote using CronniX to cause the shutdown, but to other important system files. For example, if your child had access to reset the computer's clock, then he/she could simply set the clock to run an hour slow and the computer would shut down an hour later than you had programmed it for. Mac OS X allows only the system Administrator to adjust the clock.
Earlier versions of the Mac OS, such as Mac OS 9, have no such protection. If Mac OS 9 is installed, the computer can be booted into Mac OS 9 by changing the System Preferences > Startup Disk to Mac OS 9. Fortunately, Mac OS X also prevents non-administrator users such as your child from changing the Startup Disk.
Why you should install Open Firmware Password
Even if you don't have an earlier version of the Mac OS on the hard disk, it is possible for your child to start the computer on Mac OS 9 by using a Mac OS 9 CD-ROM, or plugging an external hard drive with a bootable Mac OS 9 on it. As explained above, once your child is in OS 9, anything is possible. Open Firmware Password prevents this. You don't even have to hide your Mac OS 9 CD-ROM.
Why pathnames are used In the crontab Commands
Note that the full path is given for the commands in the crontab. The reason for this was explained to me by David Ledger, that Cron runs with a default environment which means a minimal or empty PATH. PATH is the default variable that tells the shell all the places to look for applications. Another reason you want to use the complete path is so someone can't create another executable with the same name and put it in the path so that command executes instead of the command you want executed. (Thanks, Nathan Sturtevant.)
How the commands run only when your child is logged in
The commands in each of the three entries, the display dialog and the two shutdown, are followed by the token &&. Whenever a program exits, it will have an exit status. This is "0" for "no problems" or "true", and it is non-zero for everything else. (To see the exit status of a previous command in the Terminal, type "echo $?") The "users" command makes a list of users who are currently logged in; this is "piped" by | to the grep command which is programmed to filter out all user names except that of myChildsShortName. grep returns 1 if a match or matches were found, which means that your child is currently a user, and 0 if no match was found, which means your child is not currently a user. If grep finds your child in the list of users, it will have exit status "0". The token "&&" simply means "if previous command had exit status "0" then execute whatever command comes next." This clever method was suggested by Scott J. Kramer, and thanks to Thomas Ulich for explaining it.
A longer, but less cryptic, method, was suggested by Victor Eijkhout. He gives an example using running ls instead of shutdown: The following command line wil print a list (ls) if myChildsShortName is logged in:
if ( ` /usr/bin/users | /usr/bin/grep myChildsShortName | wc -l ` > 0 ) ls
That is, test if you get more than zero lines back from the grep command. The backticks make this pipe be executed before the rest of the command.
If you have two children who have the same downtime and uptime, instead of writing separate crontab entries, use "extended grep", egrep instead of grep. Extended grep allows to match logical expressions:
users | egrep -q '(child1|child2)' This will match child1 OR child2 (the "|" means a logical "OR"). Note that you need to put this in quotation marks, otherwise the shell will interpret the "(" and ")" as delimiters of a series of commands for execution. The argument of egrep is called a "regular expression". Type "man grep" in the Terminal application for more information on grep, egrep, and fgrep. Thanks to Thomas Ulich for this idea.
How the "shutdown" command works
The unix "shutdown" command is the heart of this little scheme and is, of course, what actually shuts down the computer.
The -h "halt" option is required to actually turn off the power. If not used, the power stays on with no operating system, and you get a console like MS-DOS. Your child can re-boot the operating system by typing "fastboot".
The +0 option specifies that this is to happen in 0 minutes; i.e., immediately.
How the 5-minute warning dialog box works
The osascript command executes two applescript commands. Note that the form is:
osascript -e '...activate...' -e '...dialog...'.
The command ...activate... brings the Finder to the front. The command ...dialog.. puts up the dialog box warning of the impending shutdown. For more information on how this works, open the Script Editor application, File>Open Dictionary..., select Standard Additions, then look in "User Interaction" for "display dialog".
If you omit the commmand ...activate..., then the dialog box will not come to the front, although the Finder will bounce in the dock. This command brings all Finder windows, including the upcoming warning dialog box, to the front. I'd like to bring only the dialog box to the front, instead of all Finder windows. Please email me if you know how to do that.
The reason you must "tell the app Finder" to do display the dialog is that if you just "display dialog..." with no context, nothing happens when the user clicks the button. The reason is explained here by Axel Luttgens:
Seems to be a matter of user interaction: "display dialog" needs to be executed within a context where a user interface exists (same problem as when trying to make an AppleScript applet run as a faceless application).
who also says that if you want to launch the process in the background:
osascript -e 'tell app "Finder" to display dialog "Hey!"' &
Why the two-clause hours designations, such as "21-23,0-6"
Although it is normal for night-time to be, for example, 21-6 (9:00 PM to 6:59 AM), cron does not understand it when the ending hour number is a smaller number than the starting hour number. So we must use two clauses, one for before midnight and one for after midnight. Thanks to Thomas Ulich for this tip.
Why we put the entries in root's crontab instead of your admin account's crontab
Unix does not allow just anyone to shut down the computer using the "shutdown" command. As a non-administrator, if your child commands "shutdown", it will not work. Therefore, we must somehow tell the computer that it is you are commanding the shutdown at downtime, even if you are out in the kitchen washing dishes. There are three ways to execute "shutdown" and have it function properly:
(a) by the super-user "root"; i.e. put it in root's crontab
(b) by any user, using "sudo" and supplying a password
(c) by any user, using "sudo", but add a line to the /etc/sudoers file allowing any user to access it without supplying a password.
Now both (a) and (c) have the disadvantage of modifying a system file, but (b) is a security risk. Following the recommendation of Joe Block and Scott, I chose solution (a) since this way all your work is in one file, the root crontab, and crontabs are much more widely known, less geeky, and easier to modify (thanks to CronniX) than the /etc/sudoers file.
Method (c) was suggested by Michael Bartosh. If you prefer it, here is a comment and a line to add to /etc/sudoers which will do the job. Use the command visudo to edit /etc/sudoers. visudo works just like vi, except it does syntax checking for the sudoers file.
# Give all users access to shutdown on any host as any (ALL) user:
ALL ALL=(ALL) NOPASSWD: /sbin/shutdown
The /etc/sudoers file is really geeky. For all the gory details, read "man sudo" and then "man visudo".