How many of us dread waking up at 3am just to run some backup program on our Linux systems? Or maybe send a message to ourselves to remind us of our appointment later on in the evening. Linux comes equipped with scheduling tools. Tools that will let you get a full night's rest and still have that backup program automatically run at 3am on the dot, and even send us an email letting us know about any appointments. In this NHF, I will be discussing the at and cron scheduling utilities.
Using the at utility
The at command is used for jobs that need to be run only once. at is an interactive program and it takes in an argument, which is the time and date that you want the job to be run. All outputs of at are sent by email. So let's say it's 1pm, and we have a meeting at 3pm. In order to be reminded of this meeting at 2:30pm, we can type:
at 2:30pm
at> echo "Are you ready for your meeting???"
at> ctrl-d
We need to hit the combination ctrl-d in order to signify that we're done with what we want run. So now at 2:30pm you will recieve an email with the words "Are you ready for your meeting???' in it. Great right? Now one thing you should understand, is that at is very flexible about the time you specify. Let's say you're someone who's lived in the military all your life and you tell time military style. So you want to remove all evidence of a top secret file at 1600 hours. Then you would type:
at 1600
at> rm -rf /top-secret
at> echo "Top secret files deleted"
at> ctrl-d
At 1600 hours, the directory and everything in it will be deleted. However, when this happens, you will not receive any emails unless there is any output from running the command. So we also have at to send us an email telling us that the files have been deleted. So now you're probably wondering, what more can at do? Well for those of us who happen to be too lazy to type numbers, we can type stuff like:
at midnight
at> mail foo@bar.com -s "Where is my money?" < email.txt
at> ctrl-d
This executes the job at midnight. We can also change that to noon or teatime (which is 4pm by the way). How about being a little more specific? Let's say you need to add your IP to the /etc/hosts.allow file so you can log in at 3pm 10 days from now:
at 3pm + 10 days
at> echo "ALL: 123.456.78.9 >> /etc/hosts.allow"
at> ctrl-d
For the final example, let's say that you don't know what time it is right now, but you know that you need to call your boss up at about 40 minutes. Now you could easily lose track of time so you decide to remind yourself:
at now + 35 minutes
at> echo "Call your boss"
at> ctrl-d
So now you will get an email 5 minutes before you need to call your boss. Easy right? Keep in mind that you can run any number of commands you want with at until you enter the ctrl-d combination.
Additional at utilities
It's all good and well that you can now schedule Linux to do stuff for you. But what if you want to see what jobs are waiting to be executed, or if you want to remove a job from being executed? In order to list the current jobs that are waiting to be executed, you use the atq command. atq will list the job number as well as the time when the job is scheduled to be executed. To remove a job from being executed, you type atrm followed by the job number. Now every job has a number, and this number can be seen from the atq command. Let's take a look:
atq
20 2000-03-14 15:41 a
21 2000-03-12 16:11 a
22 2000-03-13 00:00 a
So here I see that I have three jobs waiting to be executed. Let's say I decide to remove job 21. To do so I would type:
atrm 21
That's it. To confirm this, run atq again and the job will no longer be there.
Using cron
cron, like at is used to run a program at a scheduled time. The difference is that cron is designed for jobs that need to be executed more than once. Let's say, you need to have a program run every day at 3pm. You can't do this with at. at runs the program only once and then it won't run it again unless you tell it to. cron unfortunately can be a little confusing to newbies, but once you learn it, it'll be a great help. In order to schedule commands using cron, we use the crontab command. Let's get into it right away. Let's say you want to recieve an email every minute with the words "Hello World" on it. First, type:
crontab -e
The -e flag lets you edit your current cron table. You probably don't have anything in there yet, so type the following:
* * * * * /bin/echo Hello World
What does that mean you say? Well, the first five asteriks specify the minutes, the hour, the day of month, the month, and finally, the day of the week. Now the first field ranges from 0 to 59, the second from 0 to 23, the third from 1 to 31, the fourth from 1 to 12 (or a name such as jan, feb, mar, etc...), and the last from 0 to 6 (or a name such as mon, tue, wed, etc...). The field that says /bin/echo Hello World is the command field. This is where you specify what command to run at the specified time and date. So to run this command at 2:30pm every Monday we would type:
30 14 * * mon /bin/echo Hello World
The first entry specifies 30 minutes after the hour. The second entry specifies running at 1400 hours or, 2pm. The second two entries are asteriks which means every day of the month, of every month. And finally, the last entry which specifies mon (Monday) states that we run the program every Monday only. Now if we wanted to have this run every day, we would change the field mon to an asteriks. How about a couple more examples to get you used to it:
0 2 * * * /bin/echo Hello World
What this does is runs the command on the dot of 2am every day and month. The next command will run at 5:21am, on July the 1st:
21 5 1 jul * /bin/echo Hello World
Once the program finishes running, it will wait until the next July 1st to run again. So as you can see, cron is a very flexible and very powerful program. It's important to be able to learn how to use it. Now let's try for something a little more complicated. Suppose you want the command to run on the dot of 3pm, 6pm and 11pm every day? We can use a command to separate the hours in the hour field (or any field for that matter):
0 15,18,23 * * * /bin/echo Hello World
Don't leave any spaces after the commas. Here's another example of the above that runs only on Mondays and Wednesdays:
0 15,18,23 * * mon,wed /bin/echo Hello World
Okay, that's all good, but there's a little bit more. You can also have it such that cron runs a command from a specific time to another specific time. So let's say we want to run the command from Monday to Thursday. We would do:
0 3-5 * * mon-thu /bin/echo Hello World
What this does is runs the command on Monday through Thursday from 3am through 5am daily. So now you can run any command at any time you want.
Additional flags for crontab
Additionally, crontab takes the -l flag. When run in this manner, crontab will show you your current cron table and what's scheduled to run and when. If you are running as the root user, you can also use the -u flag followed by a user name to edit that user's cron table or just to list it's contents.
Restricting scheduling
If you run a system that hosts multiple users, you might want to discourage them from using cron or at for whatever reasons. This can be done. To restrict people from using cron, create a file called /etc/cron.deny and put the name of the user you want to restrict in there. To restrict people from using at, create a file called /etc/at.deny, and put the name of the user you want to restrict in there. Be careful about restricting default system users like nobody. These accounts sometimes run their own jobs at specific times.
Conclusion
That's it. That's all you need to know about scheduling in order to make Linux more efficient and easier for you to use. Be sure to master how these commands work. Sometimes it's the only way to get work done. You can configure cron to backup your system, or to check the integrity of your filesystem and email you the results, anything.