Learning the Terminal in Jaguar, Part 2Author's Note -- In Part 1 of this series focusing on using the
Terminal application in Jaguar, you learned how to reschedule default
system cron jobs by modifying the system crontab
file.
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.
If you're running Mac OS X 10.1 (or something even older), please see Learning the Mac OS X Terminal: Part 1, which is written for earlier versions on Mac OS X.
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:
[haru:~] 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 file system (the root directory or "/"), down
to the file.
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,
looks something like this:
15 3 * * * root periodic 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.
|
Related Reading
Mac OS X in a Nutshell |
Following the user field is the sixth and final field, which holds the
actual command line that cron passes on to a shell to
execute. The heart of the command, periodic daily, tells
cron to run the periodic utility with its
daily argument.
A command's arguments are any of the additional bits of text in
the command line, including option flags, that further specify how the
command should behave. In this case, periodic's single
argument specifies that periodic run its daily job.
As you'll see more and more as you peer into Mac OS X's Unix
underpinnings, there's a lot of labor sharing among the many
specialized tools included with the system. Typically, for the system
to get a larger job done, a single, small utility will do its part,
and then pass the work on to another tool, which steps in and performs
the job it was designed for. The main duty of cron, for
example, is to launch scheduled jobs. Its strength, however, is not in
organizing, prioritizing, or reporting on those jobs (though
cron can do some of these things, and in fact did so in
Mac OS X versions prior to 10.2).
To best handle those facets of the routine maintenance jobs,
cron calls on periodic, a utility designed
specifically to run such system jobs. In this case, the daily argument
given to periodic refers to a directory of the same
name. The daily directory exists in /etc/periodic, a
place periodic knows to look for executable files to
launch. Inside /etc/periodic/daily, then, are the actual
shell scripts that perform the daily maintenance jobs.
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.
If you would like to have a look at the entire contents of the
/etc/periodic directory, you can do so using ls and its
-R flag (for recursive list), like this:
[haru:/etc/periodic] chris% ls -R /etc/periodic
daily monthly weekly
/etc/periodic/daily:
100.clean-logs 500.daily
/etc/periodic/monthly:
500.monthly
/etc/periodic/weekly:
500.weekly
The -R option flag, then, displays the contents of
that directory as well as all of its subdirectories and their
contents, completely down through the hierarchy.
As you see, there are three directories in
/etc/periodic: daily, weekly,
and monthly. Within each of these is at least one shell
script file (daily has two), whose name begin with a three-digit
number. This number specifies the order that periodic should run the
scripts, with the lower numbers running first
(100.clean-logs will run before
500.daily).
We'll take a closer look at these scripts in Part 3, but the next
steps here are to configure Mac OS X's built-in mail transfer agent
sendmail so it will operate properly, and then configure
periodic so it will email you the output of the scripts
as each is completed.
Mail user agents (MUAs) are those applications that allow you to personally send, receive, and otherwise work with your email messages. Outlook, Eudora, and Mac OS X's Mail application are familiar examples of MUAs.
Mail transfer agents (MTAs), on the other hand, are the
not-so-familiar applications that receive the messages from the MUA
and pass them on to other users on the same machine, or to MTAs on
other machines for ultimate delivery to users elsewhere. The
sendmail MTA included with OS X is one of the most
popular, used on servers large and small across the Internet.
The following procedure will walk you through the steps necessary
to get sendmail running on your machine so that it will
at least deliver the reports generated by periodic. For
help getting sendmail to run in an actual server
environment, see this
article.
The first step to getting sendmail to successfully
launch in Mac OS X is to address a permissions issue. As a security
measure, sendmail will not run with OS X's default
permissions, namely those for the root directory.
There are actually two ways to address this issue. The first and
most obvious is to simply change the offending permissions, and allow
sendmail to run. The other, less obvious solution is to
instead configure sendmail so it will ignore the somewhat
insecure permissions and run anyway.
The first method involves one simple change: eliminating write
permission for the group assigned to the root
directory. The CLI makes it very easy to view and change the various
permission settings for any item, but the procedures are still too
involved to detail here. (Of course, Mac OS X: The Missing
Manual does include an in-depth look at permissions and the
CLI.)
Instead, I'll zero in on the single command line required to get
sendmail going:
sudo chmod g-w /
Since you're modifying the settings for a root-owned directory, the
command line starts with sudo. Next comes the
chmod command, for "change (file) modes." File modes are
the settings that specify whether an item can be read or written to,
for example, and by which kind of user -- the owner of the item, its
group, or any user of the machine. (These settings correspond, of
course, with the Ownership & Permissions settings that are accessible
via Finder's Get Info window.)
Following a space are chmod's arguments, the first of
which specifies the modes to be changed. This argument says to take
the group ("g") and remove ("-") its
permission to write ("w") to the file or directory
specified in the next argument (again followed by a space), which in
this case is the root directory, ("/").
Your next step, then, is to run the command line:
[haru:~] chris% sudo chmod g-w /
|
If you ever want to revert the permissions back to group-writable, run this command, which uses the plus sign ("
|
However, there are some important caveats with this method. First,
Mac OS X upgrade installers and some application installers change the
root directory back to group-writable, so you'll need to re-run the
chmod command line whenever this happens.
Secondly, and more importantly, there's a reason why Apple wants the root directory to be group-writable. Many Classic installer applications (and even some native ones) are programmed to place items in the root directory, and unless you've given these applications admin privileges to do this, they just might choke during an installation. Apple's workaround for this possibility, then, is to keep the root directory group-writable.
Of course, that causes problems for sendmail, which
requires these permissions for security reasons. At this point, then,
you might feel stuck between a rock and a hard place. But wouldn't it
be great if you could just tell sendmail (as Ben Franklin
might), "Hey, I'm willing to give up a little security if you just
give me the liberty to keep my permissions!"
In fact, sendmail allows you to set just that option
by adding a single line to its configuration file. This is from the
sendmail documentation:
"You may have to tweak your environment to make it safer for sendmail to run. If you find that some of the safeties in sendmail are too restrictive for your environment, they can be turned off by setting the option DontBlameSendmail. The option is appropriately named as sendmail is not to be blamed for problems resulting from unsafe permissions on directories and files."
As long as you're using sendmail as described in the
tutorial and are the primary user of the machine, the security risk is
small in setting this option. If, however, you aren't able to control
access to your machine either physically or remotely, and you are
compromised, please don't blame me
So if this method sounds better for you than the first (running
sudo chmod g-w /), then the file you need to edit is
/etc/mail/sendmail.cf. You'll first want to make a
backup. Since the /etc/mail directory is only
root-writable, you'll need sudo:
sudo cp -p sendmail.cf sendmail.cf.bak
Note the use of the -p option flag in this command
line, which preserves the permissions settings of the original in the
copy of the file. This will make things a little easier, should you
need to quickly restore the file.
You can then edit this file using pico, as you have
with others. Since sendmail.cf is only writable by root,
you'll need to use sudo here as well.
sudo pico /etc/mail/sendmail.cf
This file is over 1,200 lines long and might be intimidating, but since you'll just be adding a single line near the top and then getting the heck out, you should have nothing to worry about.
As you view the file, keep in mind that lines beginning with the
#character are ignored by sendmail as it
reads the file. Typically, such lines contain descriptive comments
about the configuration settings, but they can also be actual settings
that for various reasons are turned off, or "commented out."
The line you're looking for is a commented-out "DontBlameSendmail"
line about 70 lines down from the top. The quickest way to get there
in pico is by pressing Control + W, entering
DontBlame, and pressing Return. You should then see these
lines:
# level 10 config file format
V10/Berkeley
# override file safeties - setting this option compromises system security,
# addressing the actual file configuration problem is preferred
# need to set this before any file actions are encountered in the cf file
#O DontBlameSendmail=safe
# default LDAP map specification
Next, add a new line after the found line and enter (or paste in) this line:
O DontBlameSendmail=GroupWritableDirPathSafe
When you're done, the lines should look like this:
# override file safeties - setting this option
# compromises system security, addressing the actual
# file configuration problem is preferred
# need to set this before any file actions are
# encountered in the cf file
#O DontBlameSendmail=safe
O DontBlameSendmail=GroupWritableDirPathSafe
# default LDAP map specification
As usual, press Control + O to save the file, Return to confirm the
name, and Control + X to exit pico.
If everything went well, sendmail will attempt to send
its mail the next time it's asked, even with a group-writable root
directory.
|
The version of sendmail included with Mac OS X is
compiled to look at the NetInfo database for either its configuration
information or a pointer to a config file.
In our case, we want sendmail to read from
/etc/mail/sendmail.cf so you'll need to add a record
pointing to that file to the NetInfo database. To do so, use the
niutil command with these two command lines (the second
line has been broken into two for the sake of space here, but it
should be entered on one line):
sudo niutil -create . /locations/sendmail
sudo niutil -createprop . /locations/sendmail sendmail.cf
/etc/mail/sendmail.cf
niutil, or the Netinfo Utility, is a command line
version of the GUI NetInfo Manager application found in
/Applications/Utilities. The first of the two command
lines creates a new record, and the second writes the properties of
that record: the name of the configuration file, and its path.
Now when sendmail looks at NetInfo for its
configuration information, it will find the pointer within this new
record, and follow it to /etc/mail/sendmail.cf for that
info.
The final sendmail step is configuring it to start
when the machine starts. sendmail will then continue to
run in the background whenever the machine is on, watching for new
mail to deliver, and making sure undeliverable messages don't
accumulate. Such background processes (often called daemons),
play a vital role in Mac OS X's operation, and most of the time use
little memory or processing resources.
Though running sendmail as a daemon is not really
necessary for the purpose of this tutorial, doing so will at least
ensure that the mail-related housekeeping gets done. The configuration
involves one simple step: making one change to the
/etc/hostcofig file.
Open the file in pico as usual (though you might want
to back it up first), using sudo since it's a root-owned
file:
sudo pico /etc/hostconfig
Look for this line:
MAILSERVER=-NO-
And just change the NO to YES, so it looks like this:
MAILSERVER=-YES-
Save the file and close pico as usual, and your
sendmail mail server will start with each boot. Since
sendmail is not running on your machine yet, you can also
start it without rebooting using this command:
sudo /System/Library/StartupItems/Sendmail/Sendmail start
This command manually runs the same sendmail startup
script that the system runs once MAILSERVER is set to
YES in /etc/hostconfig.
Now that sendmail is ready to go, it's time to test it
out by sending mail from the CLI. To do so, use the mail
command to send mail to yourself like this:
[haru:~] chris% mail chris
Subject:
You're now working inside the mail CLI application, so
you'll see no more tcsh shell prompts until you exit
mail. Enter any subject you would like and press
return. Type in your message at the cursor. To end your message, send
it, and exit mail, press return, type a period, and press
return again. You'll then return to your shell prompt:
[haru:~] chris% mail chris
Subject: Test
This is only a test.
.
EOT
[haru:~] chris%
You can then check your mail by entering the mail
command again, but this time with no arguments. If the message
arrives, you'll see something like this:
[haru:~] chris% mail
Mail version 8.1 6/6/93. Type ? for help.
"/var/mail/chris": 1 message 1 new
>N 1 chris Fri Jan 17 13:50 13/399 "Test"
&
You're back in the mail application, but this time to
view your new message. Press return at the "&" prompt
to have a look:
Message 1:
From root Fri Jan 17 13:50:30 2003
Date: Fri, 17 Jan 2003 13:50:30 -0800 (PST)
From: Chris Stone <chris>
To: chris
Subject: Test
This is only a test.
&
Type q and return at the prompt to exit mail:
& q
Saved 1 message in mbox
[haru:~] chris%
|
If for some reason your mail didn't arrive,
you'll want to track the problem down by looking at the mail log
The output should provide some clues, but if you're having trouble deciphering them, feel free to ask for help in the Talkback section of this article. |
Now that your MTA is working, there are only a couple of more steps
to getting periodic's reports sent to you. The first is
to configure periodic to email its reports to the root
user account instead of saving them as files. The second step is to
configure things so that any mail sent to the root
account gets forwarded to your account.
Why root? Well, we could just have
periodic send the reports directly to your account, and
it would work fine. But there is a standard practice in Unix that has
any system- generated email messages sent to root, which
is an account always sure to exist. It's then easy enough to just
change root's forwarding address once, instead of several
times should the ultimate destination account name (yours, in this
case) change in the future. For now though, it's unlikely you'll be
getting system email from processes other than periodic,
but you'll be ready if you do.
periodic reads its configuration information from the
file /etc/defaults/periodic.conf. We actually won't be
modifying this file, but having a look at it will be informative. The
/etc/defaults/periodic.conf file is a bit too long, so
you'll want to use an application that can display the files one
bite-sized screen-full, or "page," at a time. Such applications are
called pagers, and one of the most common pagers is
more.
Enter more and the file's pathname to view the first
page of the file. To view periodic's default
configuration file, then, enter:
more /etc/defaults/periodic.conf
You should then see something like this:

To move down to the next page, press the space bar. (To go back up,
press B.) At the bottom of the more display, you'll see the name of
the file being viewed, as well as an indicator of the percentage of
the file read so far. To exit more, type Q.
As you peruse the file, you'll notice its three main options sections, one for each of the periodic maintenance jobs: daily, weekly, and monthly. For us, the output line for each section is of interest. For example, in the daily options section you'll find this line:
daily_output="/var/log/daily.out" # user or /file
As you might guess, this line tells periodic to write
the output of its daily maintenance job to the file
var/log/daily.out. You'll find that each of the other two
sections have a corresponding line as well.
To have the output sent to an email message instead of this file,
you would simply replace that file's pathname in this line with the
target account's username, root, in our case. You could
just make the change in this default configuration file, but
periodic allows you the option of using an override file
with which to specify changes, thus keeping the default file pristine
and easily reverted to.
To do this, you'll create a new file
/etc/periodic.conf and add the desired output options
lines to it, and periodic will know to abide by those
specific settings in this file instead of those in its default
configuration file.
You'll again use sudo with pico since
/etc is only writable by root:
sudo pico /etc/periodic.conf
Since this file doesn't yet exist, this command will create it and
open it for writing. Simply enter these three lines to specify that
periodic sends the output from its daily, weekly, and
monthly jobs to root:
daily_output=root
weekly_output=root
monthly_output=root
Save the file and close pico as usual, and you're one
step away from finishing. The last step, then, in getting the reports
delivered is to direct them to your mailbox, instead of
root's. And you'll do this using a .forward
file.
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.
We only need, 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 finger command, which shows some basic
information about the specified account. For root's,
then:
[haru:~] chris% finger root
Login: root Name: System Administrator
Directory: /var/root Shell: /bin/tcsh
Last login Fri Oct 11 19:46 (PDT) on console
No Plan.
[haru:~] chris%
And there beside Directory you'll see that
root's home directory is /var/root.
As an alternative, you can always specify a user's home directory
using the ~ shortcut along with the account
name. Therefore, if you wanted to specify root's home
directory, you would use ~root.
Let's have a look inside ~root:
[haru:~] chris% sudo ls /var/root
.CFUserTextEncoding .forward .nsmbrc Library
First, here are a couple of points about this command line:
/Users, ~root
can only be browsed by root. Therefore, using
sudo is necessary... That initial dot is the Unix way of marking filenames
as invisible to the shell (and to the Finder as well). You can see
them, though, because you're running ls as
root, and lsshows everything to
root by default. If you were running ls as a
regular user, however, you would need to use its -a flag
to see those "dot files." For example, compare the output of these two
commands: ls -a ~ and ls ~ (they should
display the contents of your own home directory with, and without dot
files.)In any case, you should now see ~root/.forward, so
let's next edit it with pico, using sudo
since it's a root-owned file:
sudo pico /var/root/.forward
You should then see something like this:

That single line, then, is the entire content of
/var/root/.forward. To change it, 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):

Save the file and close pico as usual, and you're done with the .forward file.
Now that everything is in place, you can perform a test. Send a new mail message to root:
[haru:~] chris% mail root
Subject: Test 2
This is only a test, again.
.
EOT
[haru:~] chris%
Check your mail, and you should see the new message, forwarded to you from root:
haru:~] chris% mail
Mail version 8.1 6/6/93. Type ? for help.
"/var/mail/chris": 1 message 1 new
>N 1 chris Wed Jan 22 08:56 13/406 "Test 2"
&
Message 1:
From root Wed Jan 22 08:56:20 2003
Date: Wed, 22 Jan 2003 08:56:20 -0800 (PST)
From: Chris Stone <chris>
To: root
Subject: Test 2
This is only a test, again.
& q
Saved 1 message in mbox
[haru:~] chris%
Here are a couple of more pointers for using mail:
~/mbox. You can safely delete that file if you don't want
the messages saved. If you do keep the file and want to view the
messages, however, just run mail with its -f flag, which
will list all of your saved messages.For the final test, go ahead and run the daily maintenance job manually by entering this command:
sudo periodic daily
Once a prompt has returned, the job is done and you can check your mail once more:
[haru:~] chris% sudo periodic daily
Password:
[haru:~] chris% mail
Mail version 8.1 6/6/93. Type ? for help.
"/var/mail/chris": 1 message 1 new
>N 1 chris Wed Jan 22 09:08 59/2244 "Haru.local"
If you take a look at the message, the beginning of it should look something like this:
Message 1:
From root Wed Jan 22 09:08:54 2003
Date: Wed, 22 Jan 2003 09:08:54 -0800 (PST)
From: Chris Stone <chris>
To: root
Subject: Haru.local daily run output
Subject: Haru.local daily run output
Removing scratch and junk files:
rm: ./Mount01: is a directory
rm: ./Mount02: is a directory
rm: ./Mount03: is a directory
rm: ./Mount04: is a directory
rm: ./vi.recover: is a directory
rm: ./zBooterMnt: is a directory
Backing up NetInfo data
Checking subsystem status:
disks:
Filesystem 1K-blocks Used Avail Capacity Mounted on
/dev/disk0s9 19532400 13471036 5866040 69% /
fdesc 1 1 0 100% /dev
Now that these regular reports will be coming in, you'll probably want to be able to understand them. In Part 3, you'll get a closer look at the scripts themselves to learn how to read the reports they generate. Until then, keep checking to see that you're receiving the reports as expected, and always feel free to submit your comments or questions to our TalkBack section.
Chris Stone is a Senior Macintosh Systems Administrator for O'Reilly, coauthor of Mac OS X in a Nutshell and contributing author to Mac OS X: The Missing Manual, which provides over 40 pages about the Mac OS X Terminal.
Read more Learning the Mac OS X Terminal columns.
Return to the Mac DevCenter.
Copyright © 2009 O'Reilly Media, Inc.