oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button

Learning the Mac OS X Terminal, Part 2

by Chris Stone

The series continues in Learning the Terminal in Mac OS X, Configuring Email from the Mac OS X Terminal, Customizing the Mac OS X Terminal, and Synchronizing Drives with Cron and the Mac OS X Terminal.

However, none of the first three parts of the series will work in Mac OS X 10.2 (Jaguar) or newer. Jaguar brought several major changes to the OS that require significant changes to the procedure. I'll be posting Jaguar compatible updates to these articles shortly.

In Part 1of this series, you learned how to reschedule default system cron jobs by modifying the system crontab. Here in Part 2, I'll show you how to configure cron to email you a report each time it runs one of these jobs.

First, let's take another look at the pertinent lines in /etc/crontab. Since you only want to look at the file and not modify it, you don't need to use a text editor like pico. Instead, to only display short files like this, use the cat utility, which dumps the entire text file into your window and exits:

[localhost:~] chris% cat /etc/crontab

You might notice a couple of interesting things about this command line. First, since the permissions for /etc/crontab allow anyone to read it (but only root to modify it), using sudo is not necessary.

Second, this command line allows you to access a file in a directory other than your working directory by specifying, in this case, the full (or absolute) pathname to that file. (You didn't first cd to /etc to open crontab, as you did in Part 1.) An absolute path describes the directory hierarchy from the very top of the filesystem (the root directory or "/"), down to the file.

Related Reading

Mac OS X: The Missing ManualMac OS X: The Missing Manual
By David Pogue
Table of Contents
Full Description
Sample Chapter

Finally, because some of the crontab lines might be too long for your window, you'll need to widen the window by dragging its lower right corner to the right until all lines fit without wrapping.

Look now at the line specifying the daily cron job, which, depending on how you configured the time segment in Part 1, begins something like this:

15    17    *     *     *     root    sh /etc/daily ...

Following the first five time fields is the user field. In this case the user field tells cron to run the job as if "root" were doing it. This is necessary here because these maintenance procedures require the full access to the system allowed to the root account.

Following the user field is the sixth and final field, which specifies the actual command for cron to execute. The heart of the command, sh /etc/daily, tells cron to use sh, or the Bourne shell, to run the shell script called "daily," found in the /etc directory.

A shell script is a file holding a series of command lines that can be batch-executed by the shell. Much like an AppleScript, a shell script allows you to create and save long automated procedures that you can run at any time, using a single command. The /etc/daily shell script was written for the Bourne shell, which uses command syntax more apt for shell scripting than the tcsh shell you've been using.

The entire daily cron command line, then, looks like this:

sh /etc/daily   2>&1 | tee /var/log/daily.out  
   | mail -s "`hostname` daily output"  root

cron, in fact, uses the Bourne shell by default to execute its crontab commands, so this command wouldn't work if you ran it manually using the tcsh shell. For the purpose of this article, though, you won't need to modify this command. You won't need to fully understand it either, but this breakdown will give you a general idea of what it does:

sh /etc/daily  2>&1 |	

Run the /etc/daily shell script using the Bourne shell, and send its output and any of its error messages on to the next command.

tee /var/log/daily.out |

Write the input from the previous command to a file and also pass it on to the next command. (That's right -- you can always see the results of the latest daily cron job by viewing /var/log/daily.out.)

mail -s "`hostname` daily output"   root

Comment on this articleThis is the place for your questions and comments as you work with Mac OS X's Terminal application.
Post your comments

Using the input from the previous command as the body, create an email message with the subject "localhost daily out" and send it to root. This, then, is the command that starts the cron report's journey on its way to your mailbox.

The first step in getting the reports delivered is to direct them to your mailbox, instead of root's. To do this, you could conceivably replace "root" in this command with your account name, but wouldn't it would be simpler if you could just tell the system to redirect all mail addressed to root to your mailbox instead? By using a .forward file, you can do just that.

A .forward file is just a text file containing nothing but the name of the account to which you want the mail forwarded (in this case, your account name). Once the .forward file is placed in the home directory of the original addressee (in this case, root), the mail gets forwarded as expected.

By default, the Mac OS X root home directory already contains a .forward file, but this one redirects mail not to another user, but into thin air. This happens because instead of an account name, root's .forward file contains the pathname /dev/null, which is the location of a Unix black hole. Streams of data directed to /dev/null, mail messages included, simply disappear. Since OS X's designers figure most users won't be accessing root's mail, they used this method to ensure mail doesn't pile up at the door while no one's home, eventually filling up your hard disk.

Let's get back to Terminal, then, to edit root's .forward file. You've probably already noticed that there is no "root" directory in /Users -- so where is root's home? The easiest way to find any user's home directory is by using the ~ shortcut (for home directory), along with the account name. Therefore, to change your working directory to root's home directory, enter this:

[localhost:~] chris% cd ~root
[localhost:~root] chris%

Okay, so now you're in ~root, but where is that really? Remember, you can find out with pwd:

[localhost:~root] chris% pwd

Next, use ls to view the contents of ~root:

[localhost:~root] chris% ls 
Desktop   Documents Library 

The contents of your ~root directory might look different, but in any case, you still won't see a .forward file. What happened to it? One clue is the first character of the file's name, which is a dot ("."). An initial dot is the Unix way of marking filesnames as invisible to the shell (and to the Finder as well). But it's easy enough to see such hidden files in the CLI; just use the -a option flag with ls.

Option flags allow you to modify the behavior of commands. The -a option flag for ls tells ls to display "all" items in the working directory, including hidden ones (also known as "dot files"). Simply type the ls command, add a space, and then type the -a flag:

[localhost:~root] chris% ls -a
.		          .forward		.tcsh_history 	  Library
..		          .nsmbrc 		Desktop
.CFUserTextEncoding	  .ssh			Documents
[localhost:~root] chris%

Again, your view might be different, but you will now see ~root/.forward. You'll next want to edit it using pico. Since this file is owned by root, you'll need to use sudo as well:

[localhost:~root] chris% sudo pico .forward

First, delete the file's single line by pressing control + K. Next, type in your account name (the name that's just before the "%" in the prompt; "chris" in this case):

As you learned in Part 1, save the file with control + O, press return to confirm the name, and then press control + X to exit pico. You're done with the .forward file.

The next step in the procedure involves getting the mail transfer agent sendmail to launch successfully when beckoned by the mail user agent mail (which, as you remember, is invoked by the cron job).

Pages: 1, 2

Next Pagearrow