Книга: Fedora™ Unleashed, 2008 edition

Using cron to Run Jobs Repeatedly

Using cron to Run Jobs Repeatedly

The at and batch commands work well if you want to execute a just single task at a later date, but they are less useful if you want to run a task frequently. Instead, there is the crond daemon for running tasks repeatedly based on system — and user — requests. cron has a similar permissions system to at: Users listed in the cron.deny file are not allowed to use cron, and users listed in the cron.allow file are. An empty cron.deny file — the default — means everyone can set jobs. An empty cron.allow file means that no one (except root) can set jobs.

There are two types of jobs: system jobs and user jobs. Only root can edit system jobs, whereas any user whose name appears in cron.allow or does not appear in cron.deny can run user jobs. System jobs are controlled through the /etc/crontab file, which by default looks like this:

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
# run-parts
1  * * * * root run-parts /etc/cron.hourly
2  4 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly
The first four lines ar
e optional: SHELL specifies which shell should be used to execute the job (defaults to the shell of the user who owns the crontab file, usually /bin/bash), PATH specifies the search path for executables to use, and you should avoid using environment variables there. MAILTO defines to whom mail should be sent. If this is not set, it uses the owner of the crontab, but if you do not want to receive mail when your job runs, just set it to "". Finally, HOME specifies the home directory of the user; again, this defaults to the user's home directory if left unspecified.

The next line, # run-parts, starts with a pound sign (#) and so is treated as a comment and ignored. The next four lines are the important parts: They are the jobs themselves.

Each job is specified in seven fields that define the time to run, owner, and command. The first five commands specify the execution time in quite a quirky order: minute (0-59), hour (0-23), day of the month (1-31), month of the year (1-12), and day of the week (0-7). For day of the week, both 0 and 7 are Sunday, which means that 1 is Monday, 3 is Wednesday, and so on. If you want to specify "all values" (that is, every minute, every hour, every day, and so on), use an asterisk, *.

The next field specifies the username of the owner of the job. When a job is executed, it uses the username specified here. The last field is the command to execute.

So, the first job runs at minute 1, every hour of every day of every month and executes the command run-parts /etc/cron.hourly. The run-parts command is a simple script that runs all programs inside a given directory — in this case, /etc/cron.hourly. So, in this case, the job executes at 00:01 (1 minute past midnight), 01:01, 02:01, 03:01, and so on, and uses all the programs listed in the cron.hourly directory.

The next job runs at minute 2 and hour 4 of every day of every month, running run-parts /etc/cron.daily. Because of the hour limitation, this script runs only once per day, at 4:02 a.m. Note that it uses minute 2 rather than minute 1 so that daily jobs do not clash with hourly jobs. You should be able to guess what the next two jobs do, simply by looking at the commands they run!

Inside each of those four directories (cron.hourly, cron.daily, cron.weekly, and cron.monthly) is a collection of shell scripts that are run by run-parts. For example, in cron.daily are scripts such as rpm, which saves a list of your packages in /var/log/rpmpkgs every day; logrotate, which handles backing up of log files; and makewhatis, which updates the whatis database. You can add other system tasks to these directories if you want to, but you should be careful to ensure your scripts are correct.

CAUTION

The cron daemon reads all the system crontab files and all user crontab files once a minute (on the minute; that is, at 6:00:00, 6:01:00, and so on) to check for changes. However, any new jobs it finds are not executed until at least one minute has passed.

For example, if it is 6:01:49 (that is, 49 seconds past one minute past 6 a.m.) and you set a cron job to run at 6:02, it does not execute. At 6:02, the cron daemon rereads its configuration files and sees the new job, but is not able to execute it. If you set the job to run at 6:02 a.m. every day, it is executed the following morning and every subsequent morning.

This same situation exists when deleting jobs. If it is 6:01:49 and you have a job scheduled to run at 6:02, deleting the job makes no difference: cron runs it before it rereads the crontab files for changes. However, after it has reread the crontab file and noticed the job is no longer there, it is not executed on subsequent days.

There are alternative ways of specifying dates. For example, you can use sets of dates and times by using hyphens or commas, such as hours 9-15 would execute at 9, 10, 11, 12, 13, 14, and 15 (from 9 a.m. to 3 p.m.), whereas 9, 11, 13, 15 would miss out at the even hours. Note that it is important that you do not put spaces into these sets because the cron daemon would interpret them as the next field. You can define a step value with a slash (/) to show time division: */4 for hours means "every four hours all day," and 0 12/3 means "every three hours from midnight to noon." You can also specify day and month names rather than numbers, using three-character abbreviations: Sun, Mon, Tue, Fri, Sat for days, or Jan, Feb, Mar, Oct, Nov, Dec for months.

As well as system jobs, there are also user jobs for those users who have the correct permissions. User jobs are stored in the /var/spool/cron directory, with each user having his own file named after his username — for instance, /var/spool/cron/paul or /var/spool/cron/root. The contents of these files contain the jobs the user wants to run and take roughly the same format as the /etc/crontab file, with the exception that the owner of the job should not be specified because it is always the same as the filename.

To edit your own crontab file, type crontab -e. This brings up a text editor (vim by default, but you can set the EDITOR environment variable to change that) in which you can enter your entries. The format of this file is a little different from the format for the main crontab because this time there is no need to specify the owner of the job — it is always you.

So, this time each line is made up of six fields: minute (0-59), hour (0-23), day of the month (1-31), month of the year (1-12), day of the week (0-7), and then the command to run. If you are using vim and are new to it, press i to enter insert mode to edit your text; then press Esc to exit insert mode. To save and quit, type a colon followed by wq and press Enter.

When programming, we tend to use a sandbox subdirectory in our home directory where we keep all sorts of temporary files that we were just playing around with. We can use a personal job to empty that directory ever morning at 6 a.m. so that we get a fresh start each morning. Here is how that would look in our crontab file:

0 6 * * * rm -rf /home/paul/sandbox/*

If you are not allowed to schedule jobs, you will be stopped from editing your crontab file.

When your jobs are placed, you can use the command crontab -l to list your jobs. This just prints the contents of your crontab file, so its output is the same as the line you just entered.

If you want to remove just one job, the easiest thing to do is type crontab -e to edit your crontab file in vim; then, after having moved the cursor to the job you want to delete, type dd (two ds) to delete that line. If you want to delete all your jobs, you can use crontab -r to delete your crontab file.

Оглавление книги


Генерация: 1.953. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз