Running Linux, 5th Edition - Matthias Kalle Dalheimer [200]
Behind your back, crontab saves your commands in a file bearing your username in the /var/spool/cron /crontabs directory. (For instance, the crontab file for user mdw would be called /var/spool/cron/crontabs/mdw.) A daemon called crond reads this file regularly and executes the commands at the proper times. One of the rc files on your system starts up crond when the system boots. There actually is no command named cron, only the crontab utility and the crond daemon.
On some systems, use of cron is limited to the root user. In any case, let's look at a useful command you might want to run as root and show how you'd specify it as a crontab entry. Suppose that every day you'd like to clean old files out of the /tmp directory, which is supposed to serve as temporary storage for files created by lots of utilities.
Notice that cron never writes anything to the console. All output and error messages are sent as an email message to the user who owns the corresponding crontab. You can override this setting by specifying MAILTO=address in the crontab file before the jobs themselves.
Most systems remove the contents of /tmp when the system reboots, but if you keep it up for a long time, you may find it useful to use cron to check for old files (say, files that haven't been accessed in the past three days). The command you want to enter is
ls -l filename
But how do you know which filename to specify? You have to place the command inside a find command, which lists all files beneath a directory and performs the operation you specify on each one.
Here, we'll specify /tmp as the directory to search, and use the -atime option to find files whose last access time is more than three days in the past. The -exec option means "execute the following command on every file we find," the -type d option selects directories, and the \! inverts the selection, just choosing all items except directories (regular files, device files, and so on):
find /tmp \! -type d -atime +3 -exec ls -l { } \;
The command we are asking find to execute is ls -l, which simply shows details about the files. (Many people use a similar crontab entry to remove files, but this is hard to do without leaving a security hole.) The funny string { } is just a way of saying "Do it to each file you find, according to the previous selection material." The string \; tells find that the -exec option is finished.
Now we have a command that looks for old files on /tmp. We still have to say how often it runs. The format used by crontab consists of six fields:
minute
hour
day
month
dayofweek
command
Fill the fields as follows:
Minute (specify from 0 to 59)
Hour (specify from 0 to 23)
Day of the month (specify from 1 to 31)
Month (specify from 1 to 12, or a name such as jan, feb, and so on)
Day of the week (specify from 0 to 6, where 0 is Sunday, or a name such as mon, tue, and so on)
Command (can be multiple words)
Figure 10-1 shows a cron entry with all the fields filled in. The command is a shell script, run with the Bourne shell sh. But the entry is not too realistic: the script runs only when all the conditions in the first five fields are true. That is, it has to run on a Sunday that falls on the 15th day of either January or July—not a common occurrence! So this is not a particularly useful example.
Figure 10-1. Sample cron entry
If you want a command to run every day at 1:00 A.M., specify the minute as 0 and the hour as 1. The other three fields should be asterisks, which mean "every day and month at the given time." The complete line in crontab is:
0 1 * * * find /tmp -atime 3 -exec ls -l { } \;
Because you can do a lot of fancy things with the time fields, let's play with this command a bit more. Suppose you want to run the command just on the first day of each month.