Cron executing wrong - linux

was set on crontab the line below. But is not validate the day. When I remove de day of week is executed correctly. Any suggestion?
# uname -a
Linux server 2.6.32-358.14.1.el6.x86_64 #1 SMP Tue Jul 16 23:51:20 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
# cat /etc/issue
Red Hat Enterprise Linux Server release 6.4 (Santiago)
Kernel \r on an \m
# date
Mon Mar 2 08:50:19 BRT 2015
# crontab -l
* * 1 3 1 echo "teste"
# tail -f /var/log/cron
Mar 2 08:38:01 server CROND[10509]: (root) CMD (echo "teste")

If the time interval can't be defined in crontab, you can use a date/time check in the script itself. You can force crontab to run script at every 2nd March and check inside the script if the day is actually Monday. If not, you can exit the script.
Eg.
[[ $( date +%u ) -ne 1 ]] && exit
If the day isn't Monday, exit.

About crontab
"... there is one exception: if both "day of month" and "day of week" are restricted (not "*"), then either the "day of month" field (3) or the "day of week" field (5) must match the current day. ..."
A similar problem is said in Run a cron job on the first Monday of every month? and How to run a cron job on the first weekday of the month
So, in crontab set:
* * 1 3 * [ "$(date '+\%a')" == "Sun" ] && /bin/mkdir /tmp/cronsilvioteste

Related

get average of times that take job finish in for loop shell script

Here is my first shell script
#!/bin/bash
COUNTER=0
while [ $COUNTER -lt 10000 ]; do
date;
time wget -q 'http://exmple.com/' > /dev/null | grep real;
sleep 3;
let COUNTER=COUNTER+1
done
echo ${COUNTER} Request Sent\n
Average Response Time is :
this script download page content and calculate time of page response
i need to store Real parameter and calculate average of it
the output of script is something like that
Tue Oct 25 22:43:36
real 0m13.275s
user 0m0.004s
sys 0m0.008s
So my problems are :
How can i add some jobs (like echo ${COUNTER} ) after pressing crtl+c (stopping script)
How can i store value of "real" in seconds // sometimes page response goes to minutes , so basically need some time convert function (?)
i tried to solve the problems but as i mentioned i am training shell script
#!/bin/bash
echo "How many runs would you like to perform?"
read limit
total_time=0
counter=1
while [ ${counter} -le ${limit} ]
do
date
run_time=`(time -p wget -qO- http://exmple.com/) 2>&1 > /dev/null | grep real | awk '{print $2}'`
echo "Run ${counter} completed in ${run_time} seconds"
total_time=$(bc<<<"${total_time}+${run_time}")
if [ ${counter} -ne ${limit} ]
then
sleep 3
let counter=counter+1
fi
done
avg=$(printf "%.3f" "$(bc -l <<<"${total_time}/${limit}")")
echo "${counter} requests were sent taking ${total_time} seconds"
echo "Average response time was : ${avg} seconds"
Above is a modified script to perform the operations you requested, with a couple modifications
Added a question then input to ask how many runs to make each time, instead of a static number
Print out total time for runs and then average per run in 3 decimal places
Skip sleeping if it's the last run
You'll notice we use bc instead of let for a couple math lines. The bc command allows the use of decimal places.
https://www.gnu.org/software/bc/manual/html_mono/bc.html
To get the value in seconds I had to use awk to separate the value from the title 'real' in the line. Then you can do the math on the number value.
One other thing I noticed in your initial script. You used both ways of displaying a variable:
$COUNTER and ${COUNTER}
While both are legitimate, I got into the habit of always encapsulating my variables, it makes things easier when you want to add to the end of it.
For example let's say I have a number defined (NUM=7), but want to display it times 10. If I don't encapsulate echo $NUM0 then I get an error because the variable $NUM0 wasn't defined. But if I encapsulate echo ${NUM}0 will display an output of 70.
All of this results in a final output as below
How many runs would you like to perform?
5
Tue Oct 25 16:02:58 MST 2016
Run 1 completed in 0.09 seconds
Tue Oct 25 16:03:01 MST 2016
Run 2 completed in 0.08 seconds
Tue Oct 25 16:03:05 MST 2016
Run 3 completed in 0.07 seconds
Tue Oct 25 16:03:08 MST 2016
Run 4 completed in 0.09 seconds
Tue Oct 25 16:03:11 MST 2016
Run 5 completed in 0.08 seconds
5 requests sent taking .41 seconds
Average response time was : 0.08 seconds
Please let me know if you have any other questions about the script.
You can record a reasonably precise time with e.g.
t1=$(date +%s.%N)
wget ...
t2=$(date +%s.%N)
diff=$(($t2-$t1))
For doing stuff after Ctrl+C, which is really a SIGINT signal, read up about the trap builtin.

crontab job skipping to run randomly

I have a crontab job setup to run every 5 minutes. it runs fine without any issues. But once a while a run fails.
e.g
its run fine at 5th, 10th , 15th minute of an hour but the 20th minute will not run but runs fine again at 25th minute.
next time may be the 55th minute fails. ( random times on random servers)
i checked in /var/log/cron and there are entries for all the executed jobs but for the missed job there is not even an entry.
eg. in the below /var/log/cron job rmlogs ran fine at 21.35 missed running at 21.40 but runs again at 21.45.
Jun 12 21:35:01 [serverxxxx] CROND[4167]: (vfhttpd) CMD (/opt/vmware/vfabric-web-server/http-proxy/tools/rmlogs -t 5 >> /opt/vmware/vfabric-web-server/http-proxy/logs/rmlogs.log 2>&1 #PUPPET)
Jun 12 21:40:01 [serverxxxx] CROND[4201]: (root) CMD (/usr/lib64/sa/sa1 -S DISK -F 1 1)
Jun 12 21:41:02 [serverxxxx] CROND[4213]: (root) CMD (/usr/local/bin/monitor_mcollective >/dev/null 2>&1 #PUPPET)
Jun 12 21:45:01 [serverxxxx] CROND[4225]: (riak) CMD (/opt/riaktools/riak-create-logs -p /var/log/riak > /dev/null 2>&1 #PUPPET)
Jun 12 21:45:01 [serverxxxx] CROND[4227]: (vfhttpd) CMD (/opt/vmware/vfabric-web-server/http-proxy/tools/rmlogs -t 5 >> /opt/vmware/vfabric-web-server/http-proxy/logs/rmlogs.log 2>&1 #PUPPET)
Jun 12 21:50:01 [serverxxxx] CROND[4665]: (root) CMD (/usr/lib64/sa/sa1 -S DISK -F 1 1)
Jun 12 21:50:01 [serverxxxx] CROND[4666]: (vfhttpd) CMD (/opt/vmware/vfabric-web-server/http-proxy/tools/rmlogs -t 5 >> /opt/vmware/vfabric-web-server/http-proxy/logs/rmlogs.log 2>&1 #PUPPET)
Jun 12 21:52:01 [serverxxxx] CROND[4700]: (root) CMD (/usr/local/bin/refresh-mcollective-metadata #PUPPET)
You have a reason to doubt, if your cron job has been started every 5 minutes indeed.
To exclude the doubt you can extend the crontab line, containing your cron job with a prefix:
date >>/tmp/base_name_of_your_cronjob.log;
and check this additional log file.
If this log file contains entries every 5 minutes without a gap, then you should investigate, if /var/cron/log gets a new record for every start of the cron job, including cases, if the cron job crashes.
Additional check point is to make sure that the cron daemon has run permanently and was not restarted. You can do it by checking its process by e.g.
ps -ef|grep crond

Special crontab expression

just to verify my understanding of cron-syntax, the following expression will fire on a saturday at 02:42 in the middle of the month, right?
42 02 12-19 * 6 myScript > /dev/null 2>&1
cheers
Nicolaie
The script myScript (not good without a path here!) will be executed at 2:42 indeed, on every day between and including the 12th to the 19th of each month that is a saturday.
Actually
42 02 12-19 * 6 myScript > /dev/null 2>&1
means run on 12 thru 19 and every Saturday.
You need a more complex line to do what you state:
0 4 8-14 * * test $(date +\%u) -eq 6 && echo "2nd Saturday"
is an example from the manfile on my system. It uses a trivial execution after making sure it is Saturday.
See http://www.adminschoice.com/crontab-quick-reference/ as well as > man 5 crontab (at the commandline) for more.

Bash: Program next execution of current script using 'at'

I want to execute a script and make it schedule the next execution. A sample would be:
#!/bin/bash
TMP=/tmp/text.txt
SCRIPT=$(readlink -f $0)
date >>$TMP
at -f $SCRIPT now + 1 minutes >>$TMP 2>&1
echo -e "\n" >>$TMP
A sample execution would do as follows:
First execution OK. Schedules to next minute
Second execution writes OK but doesn't schedule
Resulting output would be:
tue mar 5 14:34:01 CET 2013
job 15 at 2013-03-05 14:35
tue mar 5 14:35:00 CET 2013
job 16 at 2013-03-05 14:36
[now at 2013-03-05 14:38]
atq outputs nothing and I don't see any /var/at/jobs (In fact, ls /var/at* outputs nothing. There is no message in any user in /var/mail/. I'm trying on a CentOS release 5.6 x86_64
Anyone has any hint as to what may be happening?
suspectus, you have hit the point... echo $SCRIPT gives '/bin/bash'... I've manually written the full path and now it works

Get Yesterday's date in solaris

I am running SunOS.
bash-3.00$ uname -a
SunOS lvsaishdc3in0001 5.10 Generic_142901-02 i86pc i386 i86pc
I need to find Yesterday's date in linux with the proper formatting passed from command prompt. When I tried like this on my shell prompt-
bash-3.00$ date --date='yesterday' '+%Y%m%d'
date: illegal option -- date=yesterday
usage: date [-u] mmddHHMM[[cc]yy][.SS]
date [-u] [+format]
date -a [-]sss[.fff]
I always get date illegal option, why is it so?
Is there anything wrong I am doing?
Update:-
bash-3.00$ date --version
date: illegal option -- version
usage: date [-u] mmddHHMM[[cc]yy][.SS]
date [-u] [+format]
date -a [-]sss[.fff]
Try this below thing. It should work
YESTERDAY=`TZ=GMT+24 date +%Y%m%d`; echo $YESTERDAY
Try this one out:
DATE_STAMP=`TZ=GMT+24 date +%Y%m%d`
where GMT is the time zone and you might need to alter the 24 according to the hours difference you have from GMT. Either that or you can change GMT to a time zone more comfortable to you e.g. CST
As larsks suggested, you can use perl:
perl -e 'use POSIX qw(strftime); print strftime "%a %b %e %H:%M:%S %Y",localtime(time()- 3600*24);'
Slightly modified from
http://blog.rootshell.be/2006/05/04/solaris-yesterday-date/
To get YYYYMMDD format use this
perl -e 'use POSIX qw(strftime); print strftime "%Y%m%d",localtime(time()- 3600*24);'
This link explains how to format date and time with strftime
http://perltraining.com.au/tips/2009-02-26.html
A pure bash solution
#!/bin/bash
# get and split date
today=`date +%Y%m%d`
year=${today:0:4}
month=${today:4:2}
day=${today:6:2}
# avoid octal mismatch
if (( ${day:0:1} == 0 )); then day=${day:1:1}; fi
if (( ${month:0:1} == 0 )); then month=${month:1:1}; fi
# calc
day=$((day-1))
if ((day==0)); then
month=$((month-1))
if ((month==0)); then
year=$((year-1))
month=12
fi
last_day_of_month=$((((62648012>>month*2&3)+28)+(month==2 && y%4==0)))
day=$last_day_of_month
fi
# format result
if ((day<10)); then day="0"$day; fi
if ((month<10)); then month="0"$month; fi
yesterday="$year$month$day"
echo $yesterday
TZ=$TZ+24 date +'%Y/%m/%d' in SunOS.
Playing on Solaris10 with non-GMT environment, I'm getting this:
# date
Fri Jul 26 13:09:38 CEST 2013 (OK)
# (TZ=CEST+24 date)
Thu Jul 25 11:09:38 CEST 2013 (ERR)
# (TZ=GMT+24 date)
Thu Jul 25 11:09:38 GMT 2013 (OK)
# (TZ=CEST+$((24-$((`date "+%H"`-`date -u "+%H"`)))) date)
Thu Jul 25 13:09:38 CEST 2013 (OK)
As You colud see, I have and I want to get CEST , but TZ=CEST+24 giving me wrong CEST data; GMT+24 giving me correct data, but unusable.
To get the proper result, I has to use GMT+22 (wrong command, correct result) or CEST+22 (wrong value, but finnaly correct result for correct TZ)
A pure bash solution given by #olivecoder is very reliable compared to any other solution but there is a mistake to be corrected. when the day fall on 1st of the month the script is failing with date saying "last_day_of_month" in day value. #olivecoder has missed $ in
day=last_day_of_month, that it should be
day=$last_day_of_month;
After this correction it works very good.
Using Timezone -24 is having some issue based on time when use it. in some cases it goes to day before yesterday. So I think its not reliable.

Resources