How to test the script deployed with crontab - linux

I have a script which I need to run daily at 01.00 am of every month. This is what I did with cron tab to make it happen
#housekeeping
0 1 1 * * sh /product/abc/tools/housekeeper.sh -t ABC
How can I check whether this script is running? Do I have to wait till it runs or is there a process running for this script so that I can confirm it is running?

The usual approach to test crontab scripts follows these guidelines:
Set the time pattern to "ten minutes from now". Wait ten minutes. Check cron's logfile and the log files of your script/app for errors.
Set the desired time pattern
This way, you can make sure that the script works. If something breaks, it must be because of the time pattern.
You should also redirect all output of the script to a log file. cron will send a mail with any output that the script produces but that's rarely desired.
If you always add an entry like "${timestamp} Started" to the log, you can check at your leisure that the script worked as expected.
If you want both, then you must make your script/app write the log file itself (i.e. without output redirection in the crontab) and print any errors to stdout; this will then make cron send an email.

Simple thing I use is to append something to a particular file before and after the desired command, like
*/2 * * * * (echo "Starting" >> ~/monitorCron.log; <Actual operation>; echo "End" >> ~/monitorCron.log;) > ~/cron.log 2>&1
This runs every 2 minutes, and appends the strings to ~/monitorCron.log.
This is the same thing I do in programming, writing a print statement where-ever and when-ever I get a doubt.

Related

How to stop minute cron job?

I have a program written in python,my program scrapes a value from some financial website every minute and pushes that value into my DB.My program takes like 1 or maximum 1.5 seconds to do this job. I have set a cron job to call my program every minute. I need to run my program in this way everyday from 09AM to 04PM. Now sometimes I may have to stop my program to kill the program at any time between 09AM to 4PM. How can I do this?
According to this link
I tried ps -o pid,sess,cmd afx | grep -A20 "cron$" and I was unable to find my program in the list since it completes it's work in seconds.
Referring to this I tried /etc/init.d/cron stop and pkill cron which kills all cron jobs which I don't want. I am running this cron in ubuntu linux .Any help with this would be appreciated.
Modify the program so it runs only if a particular file exists. Remove the file if you need to stop the program. (Or have it run only if the file doesn't exist, and touch the file to stop the program.)
If you're not able to modify the program, you can execute a shell if statement as a cron command.
simply rename the script name, so it will not be executed
Is it feasible to include a date time check within the program? And it won't run if before 9AM or after 4PM?
The following should also work:
* 9-15 * * * script.sh
0 16 * * * script.sh
To switch: perhaps have it read from a config/detect the presence of a file (acting as a flag) to determine whether or not to run.

Confusion about Crons

this is my first time writing script for cron job.
I wrote my code in shell, (which it works) and I'm trying to set it up for cron.
So here is my question. How do I set up the cron? Am I suppose to write
10 * * * * /home/workstation/deleter.sh (I want it to run every 10min)
right underneath #!/bin/sh? How would I execute it? (deleter.sh has permission via chmod)
man 1 crontab returns "No entry for crontab in section 1 of the manual"
I'm really lost and confused right now. If someone know how to set up cron please tell me!!
Thanks in advance
#!/bin/sh
counter=0
logloc=/home/ServerLogs
backup=/home/test
## Reads the location of the file systems that needs to be investigated from location.txt
## and save it into an array
while read -r line; do
Unix_Array[${counter}]=$line;
let counter=counter+1;
done < location.txt
## Reads Email recipients and save it into an array
More code continues from here......
The following will open your environment's text editor and load the crontab:
crontab -e
Your crontab entry is mostly correct. In order for your script to run every ten minutes it should be changed to:
*/10 * * * * /home/workstation/deleter.sh
The entry you indicated would run the script at the 10th minute of every hour.
To setup the cron, you can do one of two (main) things. The first would be to place the specified line in /etc/crontab. The second would be to run crontab -e and place the line in there. I would recommend to use crontab -e so the cron will execute as your own user account.
If the full path to the script is /home/workstation/deleter.sh and it does have execute-privileges, as you specified - your current line will have it execute 10-minutes past the hour, every hour. To get it to execute every 10 minutes, you'll have to use */10, like this:
*/10 * * * * /home/workstation/deleter.sh
this might help
http://www.manpagez.com/man/5/crontab/
you need to get an entry into your crontab
One of the best links I came across when I first learned about cron! Bookmark it
http://www.thegeekstuff.com/2009/06/15-practical-crontab-examples/

Crontab for script

My script is under /u01/software/aditya/script/ directory. Name of script is myscript.sh. I am able to run this script and getting output too. I am trying to set a cronjob for this script at 6.30 daily morning. I am doing this as root user. I have done following steps but not getting output.
crontab -e
30 06 * * * sh /u01/software/aditya/script/myscript.sh >> /u01/software/aditya/hello.log
:wq
but not getting any update in hello.log file :( . please help….
First check your cron log file which is usually in /var/log/syslog. There should be entries similar to
Sep 17 06:30:01 localhost CRON[17725]: (root) CMD (sh /u01/software/aditya/script/myscript.sh >> /u01/software/aditya/hello.log)
If not, your script has never been run. This could be due to a broken crontab file. You should make sure that this file always ends with a newline, better insert more than one at the end so that deleting one accidentally won't break the file.
If this line exists in the log file then your script has been run, but didn't generate any output. This can happen due to a different environment when being run via cron.
Also note that >> only redirects stdout, not stderr. If you want to redirect stderr too, then add 2>&1 at the end of the line.
Normally this is caused by a PATH problem. There is a very good chance that myscript.sh calls a command that is not available in the PATH that cron runs with. Some options to fix this are:
Make sure that every command in myscript.sh is a full path-reference (tedious)
Add source ~/.bashrc to the top of myscript.sh
Add export PATH=$PATH:<colon delimited list of paths necessary for myscript.sh to run correctly>
Pick one of the above, or you could also choose one of the options here: Hourly cron job did not run

Unix, how to put crontab in a shell script

I am new to Unix and not sure how to use crontab. I want to write a program that will update a file every midnight. 0 0 * * * (Midnight every day). I want the user to enter a value for in_variable(please look at the following code) only the first time when the program runs, and do the rest Every Midnight (without prompting the user to enter anymore values after the very first time). depending on the old input(in_variable), the program should execute the if else statement every midnight. Please let me know if this is possible? any help would be greatly appreciated.
echo "which message would you like to output: "
read in_variable
0 0 * * *
if [ $in_variable -eq "1" ]; then
echo "output message 1" >> file1
else
echo "output message 2" >> file2
fi
Cron jobs are automatic and cannot rely on any human interaction.
Your script should read its initial input from a file or its initialisation must be done with an interactive script (not from cron).
Also note that you don't specify the schedule in the shell script, but in the crontab itself. That is to say, your question is back-to-front. You should ask how to put a shell-script into a crontab? For which the answer is essentially:
See man cron. (Linked resource is for BSD, your cron implementation may be different).
Make the script to ask which message to use separate of the cron job, putting the message in a file under /var/lib. Make the cron job check for presence of the file, and then handle appending the contents if present.
crontab doesn't work like that. You don't put the time specification in the program that you want to run; you put the time specification in a crontab file somewhere (where varies by system) which specifies both when to run the program and what program or command to run.
Ignacio has it right regarding what to do with the variable: store the variable in a file in a fixed location, then have your script check for the existence of the file. Cron will have nothing to do with that part.
A quick ugly hack (more about why it is a hack after) would be:
echo "which message would you like to output: "
read in_variable
if [ $in_variable -eq "1" ]; then
echo '0 0 * * * echo "output message 1" >> file1' | crontab -
else
echo '0 0 * * * echo "output message 2" >> file2' | crontab -
fi
This is ugly because it erases the current crontab entirely. A more sophisticated answer would provide some sort of 'tag' for the new line being added to the crontab, and overwrite the old line if someone runs the script a second time. It would also provide a mechanism to remove the line, all while maintaining the preexisting cron table.

Code for stopping the overlapping of the Cron job

I need to stop the overlapping of cron jobs for example:If a cron job is scheduled at morning 2 o clock for DB backup and other cron job is scheduled at morning 7 o clock for DB backup again.So i need to stop the 7 o clock scheduled cron job if the DB backup for 2 o clock is not completed.
This is what flock is for. From man flock:
...
The third form is convenient inside shell scripts, and is usually used
the following manner:
(
flock -n 9 || exit 1
# ... commands executed under lock ...
) 9>/var/lock/mylockfile
...
In this case, flock will try to get a lock on fd 9 for /var/lock/myfile. If it can't (because the earlier job is still running), it will exit.
You need to put it in a script.
The most straightforward way to do this would be to have your 2am and 7am tasks coordinate. So for instance, the DB backup script could create a lock file when it executes, and check for the existence of this file when it starts up. If the file exists it could simply exit without doing any work (or sleep for a bit, or whatever you decide).
Doing this in a completely task-agnostic way might be possible, but it's going to be trickier and unnecessary in this particular case.
Assuming you are on a Unix system: The easiest way to do this is
create a file and write the cron job's PID to it. If the file can't be
created using open(2) with O_CREAT|O_EXCL flags, it already
exists, thus the previous job is still running or has crashed without
cleaning up. The PID can be used to determine whether the job is still
running.
In your case, the safest approach is probably for the cron job to die
if the PID file is found on startup.
Since you put the perl tag to the question, I suggest to have a look
at the File::Pid and Proc::PID::File modules.
You just need something that you can check to see if the first task has finished running, and this check should be done right before the job runs again.
I'd implement this with a database (if available) or a registery key or even a text file. So your task would look like this:
read job_flag
if job_flag == 0
step job_flag = 1
run job
step job_flag = 0
else
stop job
end
Why not just do this in a single cron job?
/path/to/job1 && /path/to/job2
Here is my solution:
$ crontab -l
* * * * * cd /patch/to/script; . /patch/to/.profile; overlap.pl process.sh -t Device || process.sh -t Device
$
$
$ cat overlap.pl
#!/usr/bin/env perl
use warnings;
use strict;
my $cmd = join(' ',#ARGV);
my #result = `pgrep -f \"$cmd\"`;
scalar #result > 2 ? exit 0 : exit 1;
EXPLANATION:
this job runs script every minute to check if it works (* * * * *)
cron job is complex, fisrt change directory, load profile so I need to launch script directly from this job not from script that is checking if overlapped
and then check if this particular process with the same parameters is already running (overlap.pl with exact command that I want to check)
if "no", return 0, if "yes", return >0
then there is logical "or" checking result and launch desired script or not
Pay attention to the array length in overlap.pl, you can check it by yourself by doing `ps -elf | grep \"$cmd\" >> /tmp/croncheck`;
You can do that just using cron. You are going to have to add some logic to your script or code to check if the other one is running or not. A total hack would be to have your script check for the exists of a particular file. If it does not exist then you should create this file, perform the backup, then remove it. If the file does exist, do nothing.
That is a hack and only really works because your jobs are spaced so far apart.

Resources