Job scheduling is a feature that allows a user to submit a command or program for execution at a specified time in the future. On a Linux server, it is important that certain tasks run at certain times The execution of the command or program could be one time or periodically based on a pre-determined time schedule. For example, scheduling system maintenance commands to run during nonworking hours is a good practice, as it does not disrupt normal business activities.
Understanding job scheduling
Linux has two daemons of scheduling jobs based on whether they’re regularly occurring: atd and crond. The cron system runs jobs repetitively at pre-specified times that can be monthly, weekly, daily, hourly, or even per minute while the at system is used for jobs scheduled one time in the future such as to run a job over the weekend. A third system, called anacron which is closely related to cron is used for running periodic jobs on a system that may not always be on like laptops. In this article, I will explain how you can use each command to schedule your tasks or jobs on your Linux server
1) Schedule tasks with the cron service
We typically schedule intensive jobs at times when the system is expected to be underused such as overnight. A daemon called crond runs in the background and check its configuration every minute to examine configuration files in order to execute commands or shell scripts specified if the time matches the time indicated. A series of configuration files under
/etc can also contain jobs and control which users are allowed to add jobs using crontab.
# ls -ld /etc/cron* drwxr-xr-x. 2 root root 4096 Aug 24 17:05 /etc/cron.d drwxr-xr-x. 2 root root 4096 Aug 24 16:03 /etc/cron.daily -rw-------. 1 root root 0 Mar 31 2016 /etc/cron.deny drwxr-xr-x. 2 root root 4096 Jun 9 2014 /etc/cron.hourly drwxr-xr-x. 2 root root 4096 Jun 9 2014 /etc/cron.monthly -rw-r--r--. 1 root root 451 Jun 9 2014 /etc/crontab drwxr-xr-x. 2 root root 4096 Jun 9 2014 /etc/cron.weekly
Managing the cron service is easy because it doesn't need to be reloaded or restarted to activate changes to their configuration. The cron daemon wakes up every minute and checks its configuration to see whether anything needs to be started. You can check its status as below
# systemctl status crond ● crond.service - Command Scheduler Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled) Active: active (running) since Sat 2017-08-19 03:12:38 UTC; 1 weeks 0 days ago Main PID: 3240 (crond) CGroup: /system.slice/crond.service └─3240 /usr/sbin/crond -n
a) Syntax of crontab files
crond executes cron jobs on a regular basis if they comply with the format defined in the /etc/crontab file. Crontables for users are located in the
/var/spool/cron directory. The other location where system crontables are stored is the
/etc/cron.d directory. Only the root user is allowed to create, modify, or delete them. The crond daemon scans entries in the files at the two locations to determine a job execution schedule. Instead of modifying
/etc/crontab, different cron configuration files are used as cron files in
/etc/cron.d or scripts in
A cron table includes six fields separated by space or tab characters. The first five fields specify the times to run the command, and the sixth field is the absolute pathname to the command to be executed. You can place commands in a shell script and schedule it to run repetitively while the sixth field is the absolute pathname to the shell script. The initial section of the cron table specifies the environment used while executing commands. The remainder of the file contains comments that identify the format of a cron table entry.
# cat /etc/crontab SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root # For details see man 4 crontabs # Example of job definition: # .---------------- minute (0 - 59) # | .------------- hour (0 - 23) # | | .---------- day of month (1 - 31) # | | | .------- month (1 - 12) OR jan,feb,mar,apr ... # | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat # | | | | | # * * * * * user-name command to be executed
The columns, in order, are:
- Minute of hour (0-59):
- Hour of day in 24 hour time (0-23): The hour of the day is listed in military time. For example, to indicate that a job is to run at 3:00 p.m., you would list 15 for that field
- Day of month (1-31)
- Month of year (1-12): you can use the first three letters of the name rather than a number if you prefer
- Day of week (0-7): both 0 and 7 correspond to Sunday. You can use the first three letters of the name rather than a number if you prefer
- Command or script to execute: after the username for the cron job, you can use a script which must be executed instead of the command
On Debian systems, the content of the crontab file looks differents as below
cat /etc/crontab # /etc/crontab: system-wide crontab # Unlike any other crontab you don't have to run the `crontab' # command to install the new version when you edit this file # and files in /etc/cron.d. These files also have username fields, # that none of the other crontabs do. SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin # m h dom mon dow user command 17 * * * * root cd / && run-parts --report /etc/cron.hourly 25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily ) 47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly ) 52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
After the first five fields,
/etc/crontab entries continue with the account name to be used when executing the program in the sixth field. For instance, a task definition in
/etc/crontab can look as follows:
# This task would start 10 minutes after 5 a.m. on December 3 only. 10 5 3 12 * nobody /usr/bin/false
# run a task every minute between 5:00 a.m. and 5:59 a.m * 5 * * * nobody /usr/bin/false
The anatomy of a single entry in this file is shown as described below
- If you want to match all values for a column (any value), use an asterisk (*)
- A list separated by commas such as 0,10,16 matches any of the specified values
- Two values separated by a dash ( - ) indicate a range, inclusive of the end points
- A slash, when used in conjunction with some other multi-value option, specifies stepped values. A stepped value is a range in which some members are skipped. For instance, */30 in the minute field indicates a job that’s run every 30 minutes
# execute the /root/process.sh shell script at 5:20 PM and 5:40 PM Monday to Friday regardless of the day of the month or month of the year 20,40 17 * * 1-5 root /root/script.sh
b) Create or edit user cron table
Normally all users are allowed to schedule jobs on Linux systems but only the root is authorized to edit the
/etc/crontab file. To create a user cron job, you use the crontab utility, not to be confused with the
/etc/crontab configuration file. The syntax for crontab is as below:
crontab [-u user] [-l | -e | -r] [file]
In detail, we have
- -u: specifies the name of the user whose crontab is to be used (when listing) or modified (when editing)
- -l: it displays the current user crontab file.
- -r: removes the current user crontab file. All cron jobs will be removed
- -e: it helps to edit the current user crontab file.
Schedule a cron to execute on every minute
Each individual user will have their own crontab file, you can use the
-e option to the crontab command, which opens the vi editor or depending on your system will propose you a list texts editors. You can then enter the appropriate cron table entries:
$ crontab -e # display the date into a file every minute * * * * * echo "it is $(date)" >> date-file
Now you can see if a crontab file of our user "paul" has been created
$ cat /var/spool/cron/paul # display the date into a file every minute * * * * * echo "it is $(date)" >> date-file
When we don't include the full path of the file, it means that the file will be created in the home directory of the user. Now we can look about our cron job
$ cat /home/paul/date-file it is Thu Aug 31 03:43:01 UTC 2017 it is Thu Aug 31 03:44:01 UTC 2017 it is Thu Aug 31 03:45:01 UTC 2017 it is Thu Aug 31 03:46:01 UTC 2017
If we didn't redirect the output into a file, it will get emailed every minute to the user
Schedule a cron to execute on every five (05) minutes
As root user, you can also edit or list the crontab of another user with
# crontab -e -u stephen # ping the gateway every 05 minutes and redirect the result in a file */5 * * * * ping -c 10 192.168.10.1 >> ping-file
# cat /home/stephen/ping-file PING 192.168.10.1 (192.168.10.1) 56(84) bytes of data. 64 bytes from 192.168.10.1: icmp_seq=1 ttl=255 time=2.07 ms 64 bytes from 192.168.10.1: icmp_seq=2 ttl=255 time=2.63 ms 64 bytes from 192.168.10.1: icmp_seq=3 ttl=255 time=1.35 ms 64 bytes from 192.168.10.1: icmp_seq=4 ttl=255 time=1.04 ms
To remove all the cron job of a user, use the command as below
# crontab -r -u paul
We can check the result as below
# crontab -l -u paul no crontab for paul
Schedule a cron to execute a script during certain time on selected days of week
You can schedule a script instead of a command
# crontab -e -u paul #run a script to check the server cpu during the time where the charge can be max 1-45 22-23 * * 0,1,4,6 /home/paul/check-cpu-script.sh >> check-cpu-file
We can check the result
# cat /home/paul/check-cpu-file CPU utilization percentage : 1%|avg=1%;40;70;0;100 cpu0=1%
Schedule multiple tasks in single cron during certain time on selected days of week
# crontab -e 11-45 18-20 * * 0,4,6 /home/paul/check-cpu-script.sh >> check-cpu-file; ping -c 10 192.168.10.1 >> check-cpu-file
we can check the file as below
# cat /home/paul/check-cpu-file CPU utilization percentage : 1%|avg=1%;40;70;0;100 cpu0=1% PING 192.168.10.1 (192.168.10.1) 56(84) bytes of data. 64 bytes from 192.168.10.1: icmp_seq=1 ttl=255 time=2.07 ms 64 bytes from 192.168.10.1: icmp_seq=2 ttl=255 time=2.63 ms
Schedule tasks with special syntax
Many administrative tasks are performed on an hourly, daily, weekly, or monthy basis. They are essential shortcuts for the equivalent numeric schedule specified:
0 * * * *to run once an hour, on the hour.
0 0 * * *to run once a day at midnight
0 0 * * 0to run once a week on Sunday at midnight.
0 0 1 * *to run at midnight on the first of the month. So schedule a cron job beginning of every month
0 0 1 1 *to run once a year at midnight on January 1. So, you can use it if you want a job to be executed on the first minute of every year
@rebootto run once after reboot
So you can schedule a backup as below
# the cron 0 0 * * * /usr/local/bin/backup.sh can be define as below @daily /usr/local/bin/backup.sh
If you have a task of this type, you don’t need to create a system cron table. Instead, you can place a shell script that runs the appropriate commands in one of the following directories:
- Scripts that should be executed hourly in the
- Scripts that should be executed daily in the
- Scripts that should be executed weekly in the
- Scripts that should be executed monthly in the
The contents of these scripts is bash shell scripting code, and they don’t contain any of the time indicators that are specific to cron. For example, to execute the script below every hour, we have to move it in the
#vim /etc/cron.hourly/check-cpu.sh #!/bin/bash echo "it is $(date)" >> script-file-result /usr/lib/nagios/plugins/check_centreon_snmp_cpu -H localhost -C public -v 2c -w 40 -c 70 >> >> script-file-result
On Ubuntu systems, cron table entries within the
/etc/crontab file are used to execute the contents of the
Some cron scheduling explanation
I will give you some cron jobs scheduling explanation which can help you as below
0 * 4 12 * command: every hours of the 4 December
50 * * * * command: every hours at 50 minutes exactly. So à 00 h 50, 4 h 50, 14 h 50, etc.
0 0 * * 1 command: every mondays at midnight (the night from sunday to monday).
45 7 1-10 * * command: every morning 7 h 45 from the 1st to 10th of every month.
0 */2 * * * command: every 2 hours (00 h 00, 02 h 00, 04 h 00…)
0 4 * 12 * command: every days of the December month at 4 AM
*/10 * * * 1-5 command: every 10 minutes from monday to friday
0 0 * * 1,3,4 command: midnight from monday, wednesday and thursday
Cron is great, but it has one weakness: it is designed for machines that are left running continuously. If your machine is turned off when a job falls due, it simply won't be run. It exists another solution which helps to execute the tasks when you server get up after.
2) Schedule tasks with the anacron service
Anacron is a simplified cron that complements the existing cron system. It is made to handle jobs that run daily or less frequently and jobs for which the precise time doesn’t matter. Anacron’s chief advantage over cron is that it runs jobs that were scheduled to go when the computer was off.
Anacron was developed to ensure that specific tasks will be executed at a guaranteed interval. That ensures that the task will also run if the system has been down for maintenance temporarily.
a) Syntax of anacron files
To ensure regular execution of the job, cron uses the anacron service. This service takes care of starting the hourly, daily, weekly, and monthly cron jobs, no matter at which exact time. To determine how this should be done, anacron uses the
/etc/anacrontab, the jobs to be executed are specified in lines that contain four fields
# cat /etc/anacrontab # /etc/anacrontab: configuration file for anacron # See anacron(8) and anacrontab(5) for details. SHELL=/bin/sh PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root # the maximal random delay added to the base delay of the jobs RANDOM_DELAY=45 # the jobs will be started during the following hours only START_HOURS_RANGE=3-22 #period in days delay in minutes job-identifier command 1 5 cron.daily nice run-parts /etc/cron.daily 7 25 cron.weekly nice run-parts /etc/cron.weekly @monthly 45 cron.monthly nice run-parts /etc/cron.monthly
The syntax of anacron can be considered as explained below:
- period (in days): The first field specifies the frequency of job execution, expressed in days. For example, a 1 (one) in this field means run it every day. We can use the special syntax "@"
- delay (in minutes): the second column specifies how long anacron waits before executing the job. The delay feature is intended to help keep the system from being overloaded if anacron determines it needs to run several commands when it starts up
- job-identifier: it identifies the command. Its purpose is to identify the job in messages, log files, and for special execution
- command: the last field is the command that should be executed
The nice command runs the command at a lower priority. run-parts is a tool that comes with cron that runs each file in the given directory one after another.
b) Schedule task with anacron
As we have seen the syntax of the anacron file which already has a content, you can insert your job as below at the end of the file
@daily 15 rsync.daily /bin/bash /home/steven/script/backuprsync.sh
if the system is down, anacron will execute the script 15 minutes after the system comes back up.
Although useful to know how anacron works, it typically is not a service that is often recommended to configure directly. The need to configure services through anacron is taken away by the cron.hourly, cron.daily, cron.weekly, and cron.monthly files. Of course, to do any good, the anacron utility must be called itself. To schedule a job in anacron you can just drop the script into the right folder and change the delay for your convenience.
Test the anacron syntax
It is possible to can check for any syntax error or other issues with the anacrontab file using the command below
# anacron -T
If there is any error, you will have a message as below which indicates the line of the error
anacron: /etc/anacrontab: Unknown named period on line 17, skipping
Run anacron job in foreground
Normally anacron forks background jobs, and it will just not display anything on the screen. But sometimes you can need to see the output on the screen itself. It is possible with the
-d parameter of the command as below:
# anacron -d Anacron started on 2017-09-01
Force the anacron job execution
To force the execution of anacron job you can use the
-f option. This option has the particularity to still consider the delay specified in the anacrontab file.
# anacron -d -f Anacron started on 2017-09-01 Will run job `cron.daily' in 34 min. Will run job `rsync.daily' in 44 min. Will run job `cron.weekly' in 54 min. Will run job `cron.monthly' in 74 min.
Force the anacron job execution immediately
-f option which forces the execution by respecting the delay, the
-n parameter forces the execution at the present instant that you launch it. It will not consider any delays.
# anacron -d -n Anacron started on 2017-09-01 Checking against 0 with 31 Will run job `rsync.daily' Jobs will be executed sequentially Job `rsync.daily' started Job `rsync.daily' terminated (exit status: 3) (mailing output) Normal exit (1 job run)
There is no other script/job on the other cron folders
3) Schedule jobs with at service
Sometimes cron and anacron are overkill. Whereas cron is used to schedule jobs that need to be executed on a regular basis, the atd service is available for services that need to be executed only once. To run a job through the atd service, you would use the at command. The at command’s tasks or jobs are queued up in the
/var/spool/at directory, with a single file representing each job.
a) at command syntax
In ordinary use, the at command only needs a single option: a time to run which can be
- a specific time (time of day): You can specify the time of day as HH:MM, optionally followed by AM or PM if you use a 12-hour format. If the specified time has already passed, the operation is scheduled for the next occurrence of that time
- a time indication: it exists keyword which stands for what you’d expect as noon (12:00), midnight (00:00), or teatime (16:00)
- a specified day: to schedule an at job more than 24 hours in advance, you must add a date specification after the time-of-day specification. This can be done in the numeric form, using the format MMDDYY, MM/DD/YY, or DD.MM.YY. Alternatively, you can specify the date as month-name day or month-name day year.
- a specified period in future: You can specify a time using the keyword
now, a plus sign
+, and a time period to run a job at the time specified.
b) create, edit, list or remove "at" jobs
After you use the at command with one of the forms above, the at shell opens. From this shell, you can type several commands that will be executed at the specific time that is mentioned. After entering the commands, use
Ctrl-D to quit the at shell.
Schedule a task at a specified time
# at 2pm at> echo "Good afternoon" at> <EOT>
You should receive a mail with the message.
Schedule a task for the future
# at 04:47 09/08/17 at> tail -f -n 30 /var/log/centreon-engine/centengine.log >> /home/paul/centengine-log at> <EOT>
You can schedule task for some weeks as below
# at now +2 weeks
List and remove scheduled tasks
After scheduling jobs with at, you can use the atq command ( q for queue ) to get an overview of all jobs currently scheduled. It is also possible to remove current at jobs with the atrm command
# atq 1 Fri Sep 1 06:19:00 2017 a root 2 Fri Sep 1 06:20:00 2017 a root 4 Fri Sep 1 05:30:00 2017 a root 3 Fri Sep 1 05:20:00 2017 a root 5 Fri Sep 1 14:00:00 2017 a root 10 Fri Sep 8 04:47:00 2017 a root
You can see the tasks which will be executed at the time specified. We can remove a task as below
# atrm 10
We can check by listing again the scheduled tasks
# atq 1 Fri Sep 1 06:19:00 2017 a root 2 Fri Sep 1 06:20:00 2017 a root 4 Fri Sep 1 05:30:00 2017 a root 3 Fri Sep 1 05:20:00 2017 a root 5 Fri Sep 1 14:00:00 2017 a root
4) Allowed and disallowed users for scheduled job
By default, all users can schedule jobs and it is possible to limit which user is allowed to schedule jobs by using some special or permissive files
a) Managing "cron" security
It is possible to limit which user is allowed to schedule cron jobs by using the
/etc/cron.deny configuration files. If the cron.allow file exists, a user must be listed in it to be allowed to use cron. If the cron.deny file exists, a user must not be listed in it to be allowed to set up cron jobs. If neither file exists, only root can manage cron jobs
b) Managing "at" security
at has a set of security files,
/etc/at.deny, which allow users to or prevent users from queuing up at jobs. If the at.allow file exists and contains usernames, only those users, and the root user are allowed to use at. If the
/etc/at.deny file exists and contains usernames, those users are denied and all others are allowed. If neither file exists, only the root user is allowed to submit at jobs.
5) Issues about path and global environment
Scripts can work fine when running in the command line but don’t work when running from cron and it is a common problem. The environment is different because cron doesn’t run the
.bashrc scripts. Therefore, you can expect a minimal environment, including a basic PATH. You can also indicate your shell environment then, follow with the cron job
# crontab -e PATH=/your_script_path:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin SHELL=/bin/bash 15 1 * * 3-7 script.sh >> script-result
We learned how to schedule jobs for future execution, to configure cron to execute jobs repeatedly at a specific time. We learned that different methods exist to tell cron when a job should be executed. Periodic tasks can be run through cron or anacron so that the systems administrator doesn’t need to run the jobs manually. If a computer is off when a scheduled cron job was to run, the job won’t be executed. Anacron solves this problem by running the job when the computer is turned on. The at facility lets you run ad-hoc jobs at a particular future time.