How many times have you found yourself doing a repetitive task at a specific time? Do you remember when you found that the database hosted on your server is generating a large amount of logs, which are gradually eating the free space on the disk? Back then, you talked with the DBA team and they told you they don’t mind if you deleted log files that are more than 6 months old. That’s fine, but you’ll have to manually delete those files every once in a while. Now it’s time for your annual vacation, the only thing you forgot to do is tell your replacement colleague to delete those files regularly. Too bad isn’t it? Indeed, and for this and other similar situations, Linux and UNIX admins use crontab and at jobs to schedule their tasks.
So how can I write a crontab job?
The first thing you have to do is define the task you want performed by crontab. Let’s use the example we mentioned at the start of the post: you want to delete all database logs that are older than 6 months. For this, you’d open a new file using your favorite editor, write the following lines of code, and save the file with a relevant name (log_archiver.sh for example):
#!/bin/bash DIR=/var/logs/database find $DIR -type f -name *.log -mtime +180 | xargs rm -f
The above code uses the find command to list all files in the directory /var/logs/database, provided that they’re modified more than 6 months ago, and they have the .log extension. Then it passes them to the rm command to delete them. The -f argument is used to prevent the rm from asking the user to confirm deletion.
Secondly, ensure that this file has read and execute permissions at least for the current user. So let’s do that:
chmod +x log_archiver.sh
Then you have to determine when you want this task to be performed, let’s say the first day in each month at 12:00 AM.
Ok you’re ready, open a new crontab job by issuing the command crontab -e. An empty file will open. Enter the following:
0 0 1 * * /path/to/log_archiver.sh
Close the file the same way you close a vi file (:wq) and your crontab job will run the first day of each month exactly at 12:00 AM.
Some examples to solidify your understanding
Crontab syntax might seem alien at first, the following examples will let you grasp it more firmly:
|Everyday at 3:30 PM||30 15 * * * /path/to/script|
|Every 10th day of every month||* * 10 * * /path/to/script|
|Every Friday||* * * * 5 /path/to/script|
|Every 4th of July||* * 4 7 * /path/to/script|
Notice that if you left the hour and/or minute at *, it will be interpreted as 0. So the “Every Friday” example will be executed every Friday at 12:00 AM.
Important crontab commands
The following commands may become handy when working with crontab jobs. You already opened the file by issuing crontab -e command. Now let’s consider the following commands as well:
crontab –l # Displays the current content of the crontab file (the jobs) crontab -r # Removes the crontab file
Temporarily disabling a job
You can delete a job as easily as deleting its line. But what if you want to disable the job temporarily? Just add a hash (#) symbol at line start to disable the job. You can also use hashes to write comments, a behavior that is strongly recommended to remind yourself of the purpose of the job. Let’s disable our delete job:
# A job to delete old database log files. # 0 0 1 * * /path/to/log_archiver.sh
The at job
Crontab is extremely useful when you want to execute jobs repetitively, but what when you want to execute a job only once?
Suppose you’re a webserver administrator. The development team wanted you to create a test environment for them where they can test some code. They’ll need this environment only till 8:00 PM today. But at that time you won’t be in office. Leaving this environment till next morning when you arrive is a security risk. Accordingly, you must instruct the server to delete this environment at 8:00 PM all by itself. I hear somebody saying “how about using a crontab job, specifying the execution time to be 20:00, then removing it next morning”. Well, that might be a solution. But I have a better one: use an at job.
To use an at job, you have one of two options:
- Specify the script you want executed
- Write your own command(s) in the at prompt
Let’s have a look at both options:
Now suppose you crafted a script to delete the test environment, you called it del_env.sh. To activate the at job, you’d use the following syntax:
at 8:00 PM /path/to/del_env.sh
May be the command you want to execute is only a line or two, so creating a script file would be an overkill. Example: you want to send a copy of the log file from the test environment to the development team before deleting the whole environment. You want to do this before 8:00 PM (let’s say 7:59 PM). In this case you type at followed by the desired time, then press enter. You’re now at the at prompt, write the command(s) you want executed line by line. When you finish, press CTRL+D to save the job and exit.
at 8:00 PM /path/to/del_env.shat 7:59 PM mail -s "Log file for test environment" email@example.com < /path/to/log_file ^D job 1 at Sat Oct 24 19:59:00 2015
Note that ^D signifies pressing CTRL and D at the same time.
Other forms of at usage
You have a lot of options available for you to schedule an at job. You already saw how to specify an exact time today. Now consider the following of the most used time options:
|noon||12:00 PM today|
|midnight||12:00 AM tomorrow|
|tomorrow||Tomorrow at the same time as the current time|
|noon tomorrow||Tomorrow at 12:00 PM|
|next week||7 days from now at the same time as the current time|
|next monday||Next Monday at the same time as now|
|8:30 PM tomorrow||Tomorrow at 8:30 PM|
|now + 30 minutes||30 minutes from the current time|
|now + 1 hour||1 hour from the current time|
|now + 2 days||2 days later at the same time as the current time|
Useful at commands
The following commands might become handy when working with at jobs:
Lists all the at commands issued by the current user. If executed as root, it will list all the at commands from all users. The output will be the job number followed by the date/time of execution and the username of the owner.
atrm <em>job number</em>
Deletes the specified at job by referencing its number
In this post you learned how to use the crontab job scheduler to execute scripts/programs at a specified date and time in a repetitive manner. You saw how the crontab syntax is used to identify when to run the job. Then you learned how the at job can be used to run a task only once. You used the interactive and the non-interactive modes of the command. You looked at the various time options that the at command accepts to give you a fine grained control over the exact time and date you want the job executed.
I hope you enjoyed this read and see you in next posts.