Wise people learn when they can; fools learn when they must - Arthur Wellesley

Sunday, 8 January 2017

LINUX-13 JOB SCHEDULING (AT/CRON)


LINUX-13 JOB SCHEDULING (AT/CRON)

I am not in front of system, but there is very important task which must be done now…

How it is possible…?

Either I go to office and do that, or I share my root credentials with someone whom I trust and elaborate the whole task along with each and every command.

In my opinion, these are the only ways.

I know what you are thinking, citrix & webex… right…?
Smart Admin… Good

But I am somewhere where no net connection available, Now Happy…??

So, coming to point… how I can do the task without being in front of system.

Answer is,

By scheduling AT & CRON job.

CRON: it is a utility that allows tasks to run in background at regular interval referring “crontab” file with help of “crond” daemon.

AT: it is same as cron but for one time only.

DAEMONS: atd & crond

·         “crond” runs a job at its scheduled time only, does not entertain for missed jobs.
·         “atd” retries a missed job at the same time next day.
·         No need to restart the daemons after creating/modifying at & cron jobs.
·         All users can schedule at & cron jobs by default.

Package for cron:

[root@rhel7-server ~]# rpm -qa cronie

cronie-1.4.11-11.el7.x86_64


FILES & DIR’s:

[root@rhel7-server ~]# 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


[root@rhel7-server cron.d]# ls -ltr /etc/cron*
-rw-r--r--. 1 root root 451 Dec 28  2013 /etc/crontab
-rw-------. 1 root root   0 Jan 27  2014 /etc/cron.deny

/etc/cron.weekly:
total 0

/etc/cron.monthly:
total 0

/etc/cron.hourly:
total 8
-rwxr-xr-x. 1 root root 392 Jan 27  2014 0anacron
-rwxr-xr-x. 1 root root 362 Apr  8  2014 0yum-hourly.cron

/etc/cron.d:
total 16
-rw-r--r--. 1 root root 235 Jan 27  2014 sysstat
-rw-r--r--. 1 root root 128 Jan 27  2014 0hourly
-rw-r--r--. 1 root root 187 Jan 27  2014 unbound-anchor
-rw-r--r--. 1 root root 108 Mar 10  2014 raid-check

/etc/cron.daily:
total 20
-rwx------. 1 root root 180 Jul 31  2013 logrotate
-rwxr-x---. 1 root root 192 Jan 26  2014 mlocate
-rwxr-xr-x. 1 root root 618 Mar 17  2014 man-db.cron
-rwx------. 1 root root 256 Mar 25  2014 rhsmd
-rwxr-xr-x. 1 root root 332 Apr  8  2014 0yum-daily.cron


WE CAN FIND CRON/AT JOBS SET BY USER AT:

/var/spool/anacron   timestamp files to record when jobs are run
/var/spool/cron/*    user’s crontab files
/var/spool/at/*      user’s at job files

LET’S SET A CRON JOB…………..

Before setting cron job, just remember a vehicle no for God’s sake.

                     MH-28 DE 5000
Why…??

Don’t ask anything, just remember it.
One more thing need to consider, all fields are space separated and should must be in single line.

Now refer to /etc/crontab file in which format is given,

# 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

Five fields,

1st   minute (0 - 59)
2nd   hour (0 - 23)
3rd   day of month (1 - 31)
4th   month (1 - 12) OR jan,feb,mar,apr ...
5th   day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat

Now some action…

But, how to check cron services are running or not…??

[root@rhel7-server /]# systemctl status crond
crond.service - Command Scheduler
   Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled)
   Active: failed (Result: signal) since Wed 2016-12-28 19:06:32 IST; 1 weeks 2 days ago
 Main PID: 685 (code=killed, signal=KILL)
   CGroup: /system.slice/crond.service

Nov 23 14:15:51 rhel7-server systemd[1]: Starting Command Scheduler...
Nov 23 14:15:51 rhel7-server systemd[1]: Started Command Scheduler.
Nov 23 14:15:51 rhel7-server crond[685]: (CRON) INFO (RANDOM_DELAY will be scaled with factor 15% if used.)
Nov 23 14:15:57 rhel7-server crond[685]: (CRON) INFO (running with inotify support)
Dec 28 19:06:32 rhel7-server systemd[1]: crond.service: main process exited, code=killed, status=9/KILL
Dec 28 19:06:32 rhel7-server systemd[1]: Unit crond.service entered failed state.

[root@rhel7-server /]# systemctl start crond
[root@rhel7-server /]# systemctl enable crond
[root@rhel7-server /]# systemctl status crond
crond.service - Command Scheduler
   Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled)
   Active: active (running) since Fri 2017-01-06 19:37:14 IST; 14s ago
 Main PID: 733 (crond)
   CGroup: /system.slice/crond.service
           └─733 /usr/sbin/crond -n

Jan 06 19:37:14 rhel7-server systemd[1]: Started Command Scheduler.
Jan 06 19:37:14 rhel7-server crond[733]: (CRON) INFO (RANDOM_DELAY will be scaled with factor 51% if used.)
Jan 06 19:37:16 rhel7-server crond[733]: (CRON) INFO (running with inotify support)
Jan 06 19:37:16 rhel7-server crond[733]: (CRON) INFO (@reboot jobs will be run at computer's startup.)
[root@rhel7-server /]#

Now let’s do it………..

How to set/edit cron job for logged-in user…??

[root@rhel7-server /]# crontab -e
5 * * * * ping 192.168.243.142 >/dev/null
10 * * * * /usr/bin/ifconfig –a


How to check the cron jobs for logged-in user…??

[root@rhel7-server /]# crontab -l
5 * * * * ping 192.168.243.142 >/dev/null
10 * * * * /usr/bin/ifconfig –a

How to set/edit cron job for other users…??

[root@rhel7-server /]# crontab -u user1 -e
no crontab for user1 - using an empty one
crontab: installing new crontab

**users can do above by themselves also.

How to check other user’s cron job entries

[root@rhel7-server /]# crontab -l -u user1
5 * * * * ping 192.168.243.142 >/dev/null
10 * * * * /usr/bin/ifconfig –a

                          OR

[root@rhel7-server /]# crontab -u user1 -l
5 * * * * ping 192.168.243.142 >/dev/null
10 * * * * /usr/bin/ifconfig –a

How to remove cron job entries…??

For user itself…

[root@rhel7-server /]# crontab -r
[root@rhel7-server /]# crontab -l
no crontab for root

Other user entry removal by root…

[root@rhel7-server /]# crontab -u user1 -r
[root@rhel7-server /]# crontab -u user1 -l
no crontab for user1

Command
Explanation
crontab -l
list the scheduled jobs
crontab -u
user specific
crontab -e
set/edit the jobs
crontab -r
remove the jobs
                    






Special Meaning Characters…………..

Strings
Explanation
(*) Asterik
Match all values in the field
(-) Hyphen
For specific range
(/) Slash
1st field /5 meaning every five minute or increment of range.
(,) Comma
To separate items or multiple values
(&&) Ampersand
for multiple commands

How to schedule the Cron Jobs System Wide………..

Directory
Description
/etc/cron.d/
Create scripts here and run them from /etc/crontab file.
/etc/cron.daily/
Once a day
/etc/cron.hourly/
Once an hour
/etc/cron.monthly/
Once a month
/etc/cron.weekly/
Once a week

What does our vehicle numbers stand for…??
MH-23 DE 5000

M:   Minute
H:   Hour
23:  Date
DE:  Month
5:   Just consider 1st digit, which mean day of week

We have some special strings also for faster execution…………..

Let’s implement, what we studied above…………………..

For Minute Field (0 - 59):

*          Every minute
0          Use “0” when we need to run it exactly 2am/3pm/5am/8pm…etc
1          For 1st minute of hour
*/5        After every 5 minute
5-8        At 5th, 6th, 7th & 8th minute
5,10,15    At 5th, 10th & 15th minute
0-21/3     At every 3 minute interval of first 0-21 minutes

For Hour Field (0 – 23):

*          Every Hour
0          At 12am
1          At 1am
*/3        After every 3 hours
5-8        At 5am, 6am, 7am & 8am
5,10,15    At 5am, 10am & 3pm
0-23/2     At every 2 hours, can also be written */2

For Date Field (1 – 31):

*          Every day
1          At 1st day of month
5-8        At 5th day, 6th day, 7th day & 8th day of month
5,10,15    At 5th day, 10th day & 15th day of month
*/3        Every 3rd day

For Month Field (1 – 12):

*          Every month
1          At 1st month
5-8        At 5th month, 6th month, 7th month & 8th month
5,10,12    At 5th month, 10th month & 12th month
may,oct,dec same as above
*/3        Every 3rd month

For Day Field (0 – 6):

*          Every day of week
0          On Sunday
1          On Monday
3-6        At Wednesday, Thursday, Friday, & Saturday
0,2,5      At Sunday, Tuesday & Friday
Sun,tues,fri same as above

Few things still remaining, like…

Special string
Meaning
@reboot
Run once, at startup.
@yearly
Run once a year, “0 0 1 1 *”.
@annually
(same as @yearly)
@monthly
Run once a month, “0 0 1 * *”.
@weekly
Run once a week, “0 0 * * 0”.
@daily
Run once a day, “0 0 * * *”.
@midnight
(same as @daily)
@hourly
Run once an hour, “0 * * * *”.











@daily /scripts/myscript1
@hourly /scripts/myscript2
@weekly /scripts/myscript3
@yearly /scripts/myscript4
@monthly /scripts/myscript4

It means the scripts will run in first minute (i.e. 00) of

When set for @daily        0 0 * * * also called as @midnight   
When set for @hourly       0 * * * *  
When set for @weekly       0 0 * * 0
When set for @yearly       0 0 1 1 *
When set for @monthly      0 0 1 * *

I think now it is overdose of cron, let’s do some other things.

How to run cron at every 30 seconds…??

Can’t… b’coz lowest unit provided is in minutes.
Do we really need to run a script in every 30 seconds…??


NOW CONSIDER ON ONE TIMER JOB “AT”

[root@rhel7-server /]# at
Garbled time
[root@rhel7-server /]# at 11am
at> echo "How are you ?"
at> <EOT>
job 2 at Sun Jan  8 11:00:00 2017

So tomorrow at 11am I will get my msg/ cmd/ script

[root@rhel7-server /]# at 11am 10 jan
at> echo "How are you ?"
at> <EOT>
job 3 at Tue Jan 10 11:00:00 2017

This entry is set to run on 10th jan at 11am.

Don’t have time, run it now…

BUT HOW…??

[root@rhel7-server /]# at now +1 min
at> echo "How are you ?"
at> <EOT>
job 4 at Sat Jan  7 15:56:00 2017

[root@rhel7-server /]# tail -2 /var/spool/mail/root
How are you ?

[root@rhel7-server /]# at now +1 hour
at> echo "How are you ?"
at> <EOT>
job 5 at Sat Jan  7 16:58:00 2017
[root@rhel7-server /]# at now +1 day
at> echo "How are you ?"
at> <EOT>
job 6 at Sun Jan  8 15:58:00 2017
[root@rhel7-server /]# at now +1 month
at> echo "How are you ?"
at> <EOT>
job 7 at Tue Feb  7 15:58:00 2017
[root@rhel7-server /]# at now +1 year
at> echo "How are you ?"
at> <EOT>
job 8 at Sun Jan  7 15:58:00 2018
[root@rhel7-server /]#

How to see, what is scheduled in “at” jobs…??

[root@rhel7-server /]# atq
2       Sun Jan  8 11:00:00 2017 a root
3       Tue Jan 10 11:00:00 2017 a root
5       Sat Jan  7 16:58:00 2017 a root
6       Sun Jan  8 15:58:00 2017 a root
7       Tue Feb  7 15:58:00 2017 a root
8       Sun Jan  7 15:58:00 2018 a root

Now I decided to delete one of my “at” jobs…

[root@rhel7-server /]# atrm 8
[root@rhel7-server /]# atq
2       Sun Jan  8 11:00:00 2017 a root
3       Tue Jan 10 11:00:00 2017 a root
5       Sat Jan  7 16:58:00 2017 a root
6       Sun Jan  8 15:58:00 2017 a root
7       Tue Feb  7 15:58:00 2017 a root

Now I have no time to fill the “at” job description every time…

[root@rhel7-server /]# cat /myscript1.sh
ping -c2 192.168.234.142
echo "how are you ?"


[root@rhel7-server /]# at -f /myscript1.sh 11am
job 9 at Sun Jan  8 11:00:00 2017

[root@rhel7-server /]# at -f /myscript1.sh 11am 20jan
job 10 at Fri Jan 20 11:00:00 2017

[root@rhel7-server /]# at -f /myscript1.sh now +10m
syntax error. Last token seen: m
Garbled time

[root@rhel7-server /]# at -f /myscript1.sh now +10 min
job 11 at Sat Jan  7 16:14:00 2017

[root@rhel7-server /]# at -f /myscript1.sh now +4 hour
job 12 at Sat Jan  7 20:05:00 2017

FINALLY I WANT CONTROL OVER “CRON/AT” JOBS…………………………..

/etc/cron.allow & /etc/cron.deny | /etc/at.allow & /etc/at.deny

By default only /etc/cron.deny & /etc/at.deny are available.

·         Syntax is same for all four files.
·         Need to enter only user name, one user per line
·         Root is always permitted, doesn’t matter it is entered in either files.
·         If the cron.allow file exists, only users listed in the file are allowed to use cron, and the cron.deny file is ignored.
·         If the cron.allow file does not exist, users listed in the cron.deny file are not allowed to use Cron.
·         The root user can always use cron, regardless of the usernames listed in the access control files.

There is one master file also available to do the same controlled by PAM.
/etc/security/access.conf


After adding the following line to the file, non-other than root can create crontabs.

-:ALL EXCEPT root :cron



at.allow / cron.allow
at.deny / cron.deny
Impact
Exists and contains user entries
Existence does not matter
All users listed in .allow file are permitted
Exists but empty
Existence does not matter
No users are permitted
Does not exists
Exists and contains user entries
All users other than those listed in .deny files are permitted
Does not exists
Exists but empty
All users are permitted
Does not exists
Does not exists
No users are permitted

WELL DONE….

CRON LOGS……………………………………………..

Now all set. Just need to know where the cron/at activities are logged in...

[root@rhel7-server ~]# tail -10 /var/log/cron
Jan  8 10:00:02 rhel7-server CROND[4066]: (root) CMD (/usr/lib64/sa/sa1 1 1)
Jan  8 10:01:01 rhel7-server CROND[4103]: (root) CMD (run-parts /etc/cron.hourly)
Jan  8 10:01:01 rhel7-server run-parts(/etc/cron.hourly)[4103]: starting 0anacron
Jan  8 10:01:01 rhel7-server anacron[4117]: Anacron started on 2017-01-08
Jan  8 10:01:01 rhel7-server anacron[4117]: Will run job `cron.daily' in 35 min.
Jan  8 10:01:01 rhel7-server anacron[4117]: Jobs will be executed sequentially
Jan  8 10:01:01 rhel7-server run-parts(/etc/cron.hourly)[4119]: finished 0anacron
Jan  8 10:01:01 rhel7-server run-parts(/etc/cron.hourly)[4103]: starting 0yum-hourly.cron
Jan  8 10:01:01 rhel7-server run-parts(/etc/cron.hourly)[4126]: finished 0yum-hourly.cron
Jan  8 10:10:01 rhel7-server CROND[4236]: (root) CMD (/usr/lib64/sa/sa1 1 1)

Let’s elaborate it in detail…………………………..

What is significance of /etc/crontab and /etc/cron.d … ??

We can set cronjobs here also by editing in /etc/crontab and by putting a script file in /etc/cron.d directory.

What is the difference…??

Both places need 7 fields to be filled.

The 6th field is for specific user, like…

*/1 * * * * user1 /usr/bin/ping -c 3 192.168.234.142 >> /tmp/etc_crontab_d

If both need same entry then why at two places…??

I created 2 cron jobs, one for /etc/crontab and other for /etc/cron.d

[root@rhel7-server ~]# cat /etc/crontab
*/1 * * * * user1 /usr/bin/ping -c 3 192.168.234.142 >> /tmp/etc_crontab

[root@rhel7-server ~]# cat /etc/cron.d/sc1.sh
*/1 * * * * user1 /usr/bin/ping -c 3 192.168.234.143 >> /tmp/etc_crontab

1st I created /tmp/etc_crontab by root, nothing happened…
When I checked /tmp/etc_crontab

[root@rhel7-server ~]# cat /tmp/etc_crontab
You have new mail in /var/spool/mail/root ç this msg was there

When I checked /var/spool/mail/root,

[root@rhel7-server ~]# tail -10 /var/spool/mail/root
X-Cron-Env: <PATH=/sbin:/bin:/usr/sbin:/usr/bin>
X-Cron-Env: <MAILTO=root>
X-Cron-Env: <HOME=/home/user1>
X-Cron-Env: <LOGNAME=user1>
X-Cron-Env: <USER=user1>
Message-Id: <20170108050201.B5A7A2333F85@rhel7-server.localdomain>
Date: Sun,  8 Jan 2017 10:32:01 +0530 (IST)

/bin/bash: /tmp/etc_crontab_d: Permission denied


[root@rhel7-server ~]# chown user1:user1 /tmp/etc_crontab

[root@rhel7-server ~]# cat /tmp/etc_crontab
PING 192.168.234.142 (192.168.234.142) 56(84) bytes of data.
64 bytes from 192.168.234.142: icmp_seq=1 ttl=64 time=0.063 ms
64 bytes from 192.168.234.142: icmp_seq=2 ttl=64 time=0.062 ms
64 bytes from 192.168.234.142: icmp_seq=3 ttl=64 time=0.064 ms

--- 192.168.234.142 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 0.062/0.063/0.064/0.000 ms
PING 192.168.234.143 (192.168.234.143) 56(84) bytes of data.
From 192.168.234.142 icmp_seq=1 Destination Host Unreachable
From 192.168.234.142 icmp_seq=2 Destination Host Unreachable
From 192.168.234.142 icmp_seq=3 Destination Host Unreachable

--- 192.168.234.143 ping statistics ---
3 packets transmitted, 0 received, +3 errors, 100% packet loss, time 2001ms
pipe 3

Now problem resolved.

Next, I removed user name “user1” from 6th field of sc1.sh at /etc/cron.d

[root@rhel7-server cron.d]# cat sc1.sh
*/1 * * * * /usr/bin/ping -c 3 192.168.234.143 >> /tmp/etc_cron_d

I got following from /var/log/cron,

Jan  8 10:59:45 rhel7-server crond[7258]: (CRON) bad username (/etc/cron.d/sc1.sh)

It is clearly stating that there is some user name related problem.

Ok… our question is still unanswered, that if both places have same syntax and o/p then why they required…??

Cron reads the files in /etc/cron.d as well as /etc/crontab, it treats the files in /etc/cron.d as in the same way as the /etc/crontab file (they follow the special format of that file, i.e. include the user field). However, they are
independent of /etc/crontab.
They (Files in /etc/cron.d) do not inherit environment variable settings from it.
The intended purpose of this feature is to allow packages that require finer control of their scheduling than the /etc/cron.{daily,weekly,monthly} directories to add a crontab file to /etc/cron.d.

So, if we need environment variables to be loaded, use /etc/crontab, if we don't, then go with a file in /etc/cron.d.
Also a reason for putting a file in /etc/cron.d can be, as pointed out in the man page, a finer scheduling control, which we also have in /etc/crontab (but that includes the environment variables).

Now I’m getting following from /var/log/cron,

Jan  8 11:47:01 rhel7-server CROND[8820]: (user1) CMD (/usr/bin/ping -c 3 192.168.234.143 >> /tmp/etc_cron_d)
Jan  8 11:48:01 rhel7-server crond[8886]: (user1) PAM ERROR (Authentication token is no longer valid; new one required)
Jan  8 11:48:01 rhel7-server crond[8886]: (user1) FAILED to authorize user with PAM (Authentication token is no longer valid; new one required)

It is clearly stating that there is some user password expiry related problem.

Reset the password, then all set.

[root@rhel7-server ~]# passwd user1

Now it is working,

Jan  8 11:51:01 rhel7-server CROND[8955]: (user1) CMD (/usr/bin/ping -c 3 192.168.234.143 >> /tmp/etc_cron_d)


TROUBLESHOOTING CRON JOBS……………………………..

·         Check for single line entry
·         Check for space in cron entry
·         Check for special meaning character’s (*,-/) placing and proper use
·         Check the user’s Mail
·         Check the /var/log/cron
·         Can redirect the o/p of cron also for better understanding
·         Check the crond service status
·         Check the crond process status
·         If multiple commands are in cron then better to place them in new line
·         Check if the “time” of system has been changed, then restart crond or remove and recreate the same entry.
·         There is difference between “ping” and “/usr/bin/ping”, check for PATH
·         Ensure the file inside /etc/cron.{hourly,daily,weekly,monthly} has execute permissions.
·         Tell the system what to use when executing your script (#!/bin/sh) inside /etc/cron.{hourly,daily,weekly,monthly}
·         Check for user password expiry.
·         Check for irregular job scheduling, /2, /5, /6 are ok but /9, /11, /13 will change the timings after completing 0-59 minute cycle.
·         Following error messages are already covered before,

Error Msg: /bin/bash: /tmp/etc_crontab_d: Permission denied

Error Msg: Jan  8 10:59:45 rhel7-server crond[7258]: (CRON) bad username (/etc/cron.d/sc1.sh)

Error Msg: Jan  8 11:48:01 rhel7-server crond[8886]: (user1) PAM ERROR (Authentication token is no longer valid; new one required)
Jan  8 11:48:01 rhel7-server crond[8886]: (user1) FAILED to authorize user with PAM (Authentication token is no longer valid; new one required)

1 comment:

  1. A cron job is a Linux command used for scheduling tasks to be executed sometime in the future. This is normally used to schedule a job that is executed periodically – for example, to send out a notice every morning. Some scripts, such as Drupal and WHMCS may require you to set up cron jobs to perform certain functions.
    Your Blog is amazing. If you want to know that HOW TO SETUP A CRON JOB then,
    Click here for more information:
    HOW TO SETUP A CRON JOB

    ReplyDelete