{"id":5620,"date":"2019-09-21T14:13:31","date_gmt":"2019-09-21T18:13:31","guid":{"rendered":"http:\/\/www.linux-databook.info\/?page_id=5620"},"modified":"2019-09-21T14:13:31","modified_gmt":"2019-09-21T18:13:31","slug":"scheduling-tasks-with-cron","status":"publish","type":"page","link":"http:\/\/www.linux-databook.info\/?page_id=5620","title":{"rendered":"Scheduling tasks with cron"},"content":{"rendered":"\n<p style=\"text-align:left\" class=\"has-medium-font-size\"><strong>so you don&#8217;t have to stay up late<\/strong><\/p>\n\n\n\n<p>Being a SysAdmin has its advantages but it also has some\nchallenges. I have no time to spare in the evenings to run commands\nand scripts that need to be run during off-hours. There are many\ntasks that need to be performed off-hours when no one is expected to\nbe using the computer or, even more importantly, on a regular basis\nat specific times. \n<\/p>\n\n\n\n<p>I don&#8217;t want to have to get up at oh-dark hundred to start a\nbackup or major update, so I use two service utilities that allow me\nto run commands and programs, tasks, at predetermined times. The <strong>cron<\/strong>\nand <strong>at<\/strong> services give SysAdmins the ability to schedule tasks\nto be run at a time or times in the future.<\/p>\n\n\n\n<p>The <strong>cron<\/strong> service\ncan be used to schedule tasks on a repetitive basis, such as daily,\nweekly, or monthly. This\narticle will provide an\nintroduction to the cron\nservice and how to use it.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">cron<\/h2>\n\n\n\n<p>I use the <strong>cron<\/strong> service\nto schedule obvious\nthings like regular backups\nthat occur every day at\n2:00AM. I also do a couple less obvious things. All\nof my many computers have their system times, that is the operating\nsystem time, set using NTP \u2013 the Network Time Protocol. NTP sets\nthe system time; it does not set the hardware time which can drift. I\nuse cron to set the hardware time using the system time. I\nalso have a Bash program I run early every morning that creates a new\n\u201cmessage of the day\u201d (MOTD) on each computer that\ncontains information such as disk usage that should be current in\norder to be useful. Many\nsystem processes use cron to schedule tasks as well. Services\nlike logwatch, logrotate, and rkhunter, all use the cron service to\nrun programs every day. \n<\/p>\n\n\n\n<p>The crond daemon is the background\nservice that enables cron functionality.<\/p>\n\n\n\n<p>The cron service\nchecks for files in the\n\/var\/spool\/cron and\n\/etc\/cron.d directories,\nand the\n\/etc\/anacrontab file.\nThe contents of these files define cron jobs that are to be run at\nvarious intervals. The individual user cron files are located in\n\/var\/spool\/cron, and system\nservices and applications\ngenerally add cron job files in the \/etc\/cron.d directory. The\n\/etc\/anacrontab is a special\ncase that will be covered further on in this article.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Using crontab<\/h3>\n\n\n\n<p>Each user, including root, can have a cron file. By default no\nfile exists, but using the <strong>crontab <\/strong><strong>-e<\/strong> command as shown\nin Figure 1 to edit a cron file creates them in the \/var\/spool\/cron\ndirectory. I strongly recommend that you not use a standard editor\nsuch as vi, vim, emacs, nano, or any of the many other editors that\nare available.  Using the crontab command does not only allow you to\nedit the command, it also restarts the crond daemon when you save and\nexit from the editor. The crontab command uses vi as its underlying\neditor because vi is always present on even the most basic of\ninstallations.<\/p>\n\n\n\n<p>All cron files are empty the first time you edit it so you must\ncreate it from scratch. I added the job definition example in Figure 1\nto my own cron files just as a quick reference. Feel free to copy it\nfor your own use.<\/p>\n\n\n\n<p>In\nFigure 1 the first three lines set up a default environment. Setting\nthe environment to that necessary for a given user is required\nbecause cron does not\nprovide an environment of any kind. The SHELL variable specifies the\nshell to use when commands are executed. In this case it specifies\nthe Bash shell. The  MAILTO variable sets the email address to which\ncron job results will be sent. These\nemails can provide the status of backups, updates, or whatever, and\nconsist of the output from the programs that you would see if you ran\nthem manually from the command line. The last of these three lines\nsets up the PATH for this environment. Regardless of the path set\nhere, however, I always like to prepend the fully qualified path to\neach executable.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># <strong>crontab -e<\/strong>\nSHELL=\/bin\/bash\nMAILTO=root@example.com\nPATH=\/bin:\/sbin:\/usr\/bin:\/usr\/sbin:\/usr\/local\/bin:\/usr\/local\/sbin\n# For details see man 4 crontabs\n# Example of job definition:\n#.---------------- minute (0 - 59)\n # |  .------------- hour (0 - 23)\n # |  |  .---------- day of month (1 - 31)\n # |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...\n # |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat\n # |  |  |  |  |\n # *  *  *  *  * user-name  command to be executed\n # backup using the rsbu program to the internal 4TB HDD and then 4TB external\n 01 01 * * * \/usr\/local\/bin\/rsbu -vbd1 ; \/usr\/local\/bin\/rsbu -vbd2\n # Set the hardware clock to keep it in sync with the more accurate system clock\n 03 05 * * * \/sbin\/hwclock --systohc\n # Perform monthly updates on the first of the month\n # 25 04 1 * * \/usr\/bin\/dnf -y update <\/pre>\n\n\n\n<p>\n\t<em>Figure\n\t1: The crontab command is used to view or edit the cron files.<\/em><\/p>\n\n\n\n<p>There\nare several comment lines that detail the syntax required to define a\ncron job. I think\nthat they are mostly\nself-explanatory so I will use the entries in\nFigure 1 as examples, then\nadd a few more that will show you some of the more advanced\ncapabilities of crontab files.<\/p>\n\n\n\n<p>The line shown in Figure 2, below, runs my self-written Bash shell script, <strong>rsbu<\/strong>, to perform backups of all my systems. This job is kicked off at 1 minute after 1AM every day. The splat\/star\/asterisks (*) in positions 3, 4, and 5 of the time specification are like file globs for those time divisions; they match every day of the month, every month, and every day of the week. This line runs my backups twice; once to backup onto an internal dedicated backup hard drive, and once to backup onto an external USB hard drive that I can take to the safe deposit box.  <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">01 01 * * * \/usr\/local\/bin\/rsbu -vbd1 ; \/usr\/local\/bin\/rsbu -vbd2<\/pre>\n\n\n\n<p> <em>Figure 2: This line in my \/etc\/crontab runs a script that performs backups for my systems.<\/em><\/p>\n\n\n\n<p>The\nline shown in Figure 3\nsets the\nhardware clock on the computer using the system clock as the source\nof an accurate time. This line is set to run at 3 minutes after 5AM\nevery day. \n<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\n\t03 05 * * * \/sbin\/hwclock --systohc<\/pre>\n\n\n\n<p> <em>Figure 3: This line sets the hardware clock using the system time as the source.<\/em><\/p>\n\n\n\n<p>The last cron job in Figure 1 has been commented out, but I had been using it to perform a dnf or yum update at 04:25AM on the first day of each month. I have commented that one out so it no longer runs.  <\/p>\n\n\n\n<p>Now\nlet&#8217;s do some things that are a little more interesting than the\nbasics I have shown you so far. Suppose you want to run a particular\njob every\nThursday at 3PM. Something like that would look like Figure 4.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">00 15 * * Thu \/usr\/local\/bin\/mycronjob.sh<\/pre>\n\n\n\n<p> <em>Figure 4: This line runs myjob.sh every Thursday at 3PM.<\/em><\/p>\n\n\n\n<p>Another requirement might be to run quarterly reports after the end of the quarter. The cron service has no option for \u201cThe last day of the month,\u201d so we use the first day of the following month. This requirement does assume that the data needed for the reports will be ready at the time the job is run. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">02 03 1 1,4,7,10 * \/usr\/local\/bin\/reports.sh<\/pre>\n\n\n\n<p> <em>Figure 5: This cron job runs quarterly reports on the first day of the month after the quarter ends.<\/em><\/p>\n\n\n\n<p>Figure 6 is an example of running a job at one minute past every hour between 9:01AM and 5:01PM.  <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\n\t01 09-17 * * * \/usr\/local\/bin\/hourlyreminder.sh<\/pre>\n\n\n\n<p> <em>Figure 6: Sometimes you only want to run jobs during normal business hours.<\/em><\/p>\n\n\n\n<p>I have encountered situations where running a job every 2, 3, or 4 hours is needed. That can be accomplished  by dividing the hours by the desired interval, such as *\/3 for every three hours, or 6-18\/3 to run every three hours between 6AM and 6PM. The other time divisions can also be divided like this. The expression *\/15 in the minutes division means to run the job every fifteen minutes. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> *\/15 08-18\/2 * * * \/usr\/local\/bin\/mycronjob.sh<\/pre>\n\n\n\n<p>\n\t<em>Figure\n\t7: This cron job runs every five minutes between 0800 and 1858.<\/em><br>Note that the division expressions must\nresult in a remainder of zero (0) in order for the job to run. That\nmeans that in Figure 7 the times that the job runs will be 08:05,\n08:10, 08:15, etc, 10:05, 10:10, etc, during all of the even numbered\nhours but not during any odd numbered hours. The job will not run at\nall from 7PM through 7:59AM. \n\n<\/p>\n\n\n\n<p>I am sure you can extrapolate many other possibilities based on\nthese few examples. \n<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Limiting cron access by users<\/h4>\n\n\n\n<p>Due\nto possible misuse of cron by non-root users that might cause system\nresources such as memory and CPU time to be swamped, the SysAdmin can\nlimit user access to cron. To\nprevent all non-root users from having access to cron, simply create\nthe empty file \/etc\/cron.allow. Only users listed in that file are\nallowed access to create cron jobs. \n<\/p>\n\n\n\n<p>The root user cannot be prevented from\nusing cron. \n<\/p>\n\n\n\n<p>While preventing regular\nnon-privileged users from using cron themselves, it may be necessary\nto run sron jobs for them. Their cron jobs can be added to the root\ncrontab. \u201cBut wait!\u201d You say. \u201cDoesn&#8217;t that run those jobs as\nroot?\u201d It does not necessarily have to. The\nuser name shown in the comments for the job definition specifications\nin Figure 1\nis for when the root crontab is used to run jobs for another user. In\nthat case the program is run as the specified\nnon-root user and does not have root privileges. \n<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>cron.d<\/strong><\/h4>\n\n\n\n<p>The directory \/etc\/cron.d is\nwhere some\napplications such as SpamAssassin and sysstat install cron files.\nBecause there is no spamassassin or sysstat user, these programs need\na place to locate cron files so\nthey are placed in \/etc\/cron.d.<\/p>\n\n\n\n<p>The \/etc\/cron.d\/sysstat file in\nFigure 8 contains cron jobs\nthat relate to SAR \u2013 System Activity Reporting.  These cron files\nhave the same format as a user cron file. \n<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># Run system activity accounting tool every 10 minutes\n*\/10 * * * * root \/usr\/lib64\/sa\/sa1 1 1\n# Generate a daily summary of process accounting at 23:53\n53 23 * * * root \/usr\/lib64\/sa\/sa2 -A <\/pre>\n\n\n\n<p> <em>Figure 8: The sysstat package installs the \/etc\/cron.d\/sysstat cron file to run programs for the System Activity Reporting tool, SAR.<\/em><\/p>\n\n\n\n<p>The sysstat cron file has two lines that perform tasks. The first line runs the sa1 program every ten minutes to collect data which is stored in special binary files in the \/var\/log\/sa directory. Then every night at 23:53, the sa2 program is run in order to create a daily summary. <\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Scheduling tips<\/h4>\n\n\n\n<p>Some of the times I have set in the crontab files for my various\nsystems seem rather random and to some extent they are. Trying to\nschedule cron jobs can be challenging especially as the number of\njobs increases. I usually only have a couple tasks to schedule on\neach of my own computers so it is a bit easier than some of the\nproduction and lab environments I have worked. \n<\/p>\n\n\n\n<p>One system for which I was the SysAdmin usually had around a dozen\ncron jobs that needed to run every night and an additional three or\nfour that had to run on weekends or the first of the month. That was\na challenge because if too many jobs ran at the same time, especially\nthe backups and compiles, the system would run out of RAM and then\nnearly fill the swap file which resulted in system thrashing while\nperformance tanked so that nothing got done. We added more memory and\nwere able to do a better job of scheduling tasks. Adjusting the task\nlist included removing one of the tasks which was very poorly written\nand which used large amounts of memory.<\/p>\n\n\n\n<p>The crond service assumes that the host computer runs all the\ntime. What that means is that if the computer is turned off for a\nperiod of time and cron jobs were scheduled for that time, they will\nbe ignored and will not run until the next time they are scheduled.\nThis might cause problems if the cron jobs that did not run were\ncritical. So there is another option for running jobs at regular\nintervals.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">anacron<\/h3>\n\n\n\n<p>The anacron program performs the same function as crond but it\nadds the ability to run jobs that were skipped if the computer was\noff or otherwise unable to run the job for one or more cycles. This\nis very useful for laptops and other computers that get turned off or\nput in sleep mode. \n<\/p>\n\n\n\n<p>As soon as the computer is turned on and booted, anacron checks to\nsee whether configured jobs have missed their last scheduled run. If\nthey have, those jobs are run immediately, but only once no matter\nhow many cycles have been missed. For example, if a weekly job was\nnot run for three weeks because the system was shut down while you\nwere away on vacation, it would be run soon after you turn the\ncomputer on, but it would be run once not three times. \n<\/p>\n\n\n\n<p>The anacron program provides some easy options for running\nregularly scheduled tasks. Just install your scripts in the\n\/etc\/cron.[hourly|daily|weekly|monthly] directories, depending on how\nfrequently they need to be run. \n<\/p>\n\n\n\n<p>How does this work? The sequence is simpler than it first appears.\n<\/p>\n\n\n\n<p>First, the crond service runs the cron job specified in \/etc\/cron.d\/0hourly as seen in Figure 9.  <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># Run the hourly jobs \nSHELL=\/bin\/bash \nPATH=\/sbin:\/bin:\/usr\/sbin:\/usr\/bin \nMAILTO=root 01 * * * * root run-parts \/etc\/cron.hourly <\/pre>\n\n\n\n<p><em>Figure 9: The contents of \/etc\/cron.d\/0hourly cause the shell scripts located in \/etc\/cron.hourly to run.<\/em> <\/p>\n\n\n\n<p>The cron job specified in \/etc\/cron.d\/0hourly runs the run-parts program once per hour and the run-parts program runs all of the scripts located in the \/etc\/cron.hourly directory.<\/p>\n\n\n\n<p> The \/etc\/cron.hourly directory contains the 0anacron script which runs the anacron program using the \/etdc\/anacrontab configuration file shown in Figure 10.<\/p>\n\n\n\n<p><code># \/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 <\/code><\/p>\n\n\n\n<p><em>Figure 10: The contents of \/etc\/anacrontab file runs the executable files in the cron.[daily|weekly|monthly] directories at the appropriate times.<\/em>  <\/p>\n\n\n\n<p>The anacron program runs the programs located in \/etc\/cron.daily once per day; it runs the jobs located in \/etc\/cron.weekly once per week, and the jobs in cron.monthly once per month. Note the specified delay times in each line that helps prevent these jobs from overlapping themselves and other cron jobs.<\/p>\n\n\n\n<p>Instead of placing complete Bash programs in the cron.X\ndirectories, I install them in the \/usr\/local\/bin directory which\nallows me to run them easily from the command line. Then I add a\nsymlink in the appropriate cron directory, such as \/etc\/cron.daily.<\/p>\n\n\n\n<p>The anacron program is not designed to run programs at specific\ntimes. Rather, it is intended to run programs at intervals that begin\nat the specified times such as 3AM (see the START_HOURS_RANGE in Figure 10)\nof each day, on Sunday to begin the week, and the first day of the\nmonth. If any one or more cycles are missed, then anacron will run\nthe missed jobs one time as soon as possible.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Final thoughts<\/h2>\n\n\n\n<p>I use most of these methods for scheduling tasks to run on my\ncomputers. All of those tasks are ones that need to run with root\nprivileges. I have seen only a few times when users had a real need\nfor any type of cron job. One example I have seen of user cron jobs\nis for a developer to kick off a daily compile in a development lab. \n<\/p>\n\n\n\n<p>It is important to restrict access to cron functions by non-root\nusers. However there are circumstances when it may be necessary for a\nuser to set tasks to run at pre-specified times and cron can allow\nusers to do that when necessary. SysAdmins realize that many users do\nnot understand how to properly configure these tasks using cron and\nthe users make mistakes in the configuration. Those mistakes may be\nharmless but, more often than not, they can cause problems for\nthemselves and other users. By setting functional policies that cause\nusers to interact with the SysAdmin those individual cron jobs are\nmuch less likely to interfere with other users and other system\nfunctions.<\/p>\n\n\n\n<p>It is possible to set limits on the total resources that can be\nallocated to individual users or groups, but that is an article for\nanother time.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Resources<\/h2>\n\n\n\n<p>The <strong>man<\/strong> pages for cron, crontab, anacron, anacrontab, and run-parts all have excellent information and descriptions of how the cron system works. <br> <br> <br> <\/p>\n","protected":false},"excerpt":{"rendered":"<p>so you don&#8217;t have to stay up late Being a SysAdmin has its advantages but it also has some challenges. I have no time to spare in the evenings to run commands and scripts that need to be run during&hellip;<\/p>\n<p class=\"more-link-p\"><a class=\"more-link\" href=\"http:\/\/www.linux-databook.info\/?page_id=5620\">Read more &rarr;<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"parent":677,"menu_order":9,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-5620","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"http:\/\/www.linux-databook.info\/index.php?rest_route=\/wp\/v2\/pages\/5620","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.linux-databook.info\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"http:\/\/www.linux-databook.info\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"http:\/\/www.linux-databook.info\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.linux-databook.info\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=5620"}],"version-history":[{"count":3,"href":"http:\/\/www.linux-databook.info\/index.php?rest_route=\/wp\/v2\/pages\/5620\/revisions"}],"predecessor-version":[{"id":5623,"href":"http:\/\/www.linux-databook.info\/index.php?rest_route=\/wp\/v2\/pages\/5620\/revisions\/5623"}],"up":[{"embeddable":true,"href":"http:\/\/www.linux-databook.info\/index.php?rest_route=\/wp\/v2\/pages\/677"}],"wp:attachment":[{"href":"http:\/\/www.linux-databook.info\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5620"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}