Run script on particular day

Hi Guys,

I am having a driving script which calls internally multiple scripts


sh main_script.sh > main_script.log

inside main_script.sh

sh -x script_1.sh

sh -x script_2.sh

sh -x script_3.sh



I Have to run the internal scripts in partcular dates

script_1.sh - 25th of every month
script_2.sh - daily
script_3.sh - Every quaterly month end


Use cron/crontab!
Man pages:

man crontab

Month end cannot be specified in crontab. How about the 1st of each month?

I know its possible in crontab but can it be handled in script itslef like before trigerring each of the sub scripts

Yes, of course: there is the date command, which will tell you the current time and date. Use a format specifier to get the part of the date you want to base your condition on and use if... to conditionally run the script.

Example: run the script myscript only on 25th of the month (have a look at man date to understand what %d means):

if [ $(date '+%d') -eq 25 ] ; then
     myscript
fi

I hope this helps.

bakunin

1 Like

what if script_1.sh fails then if i rerun the main_script.sh it should run only script_1.sh . For eg script_1.sh fails on 25th and re-running on 26th in that case script_1.sh will not run and other script_2.sh will also run which would have completed being daily job

I suggest reading up on the test - command (this is effectively what [..] is). You have many possibilities to formulate various conditions on when and when not to run a script, you just need to implement them. It is far easier and in the long run less time-consuming for you to learn that (takes about 10 minutes) than to ask over and over again like you are doing now.

But first you should define what "script fails" means: does it exit with a non-zero return code? Does it write a log with an error message? Does it (not) produce a file? The secret of writing good scripts is to first make up your mind what exactly you want to do and under which conditions, then to define exactly what it is you want to do: "i need a file today" is less exact than "i need a file every second friday of the month" and this in turn is less exact than "i need a file every second friday only if this other file is up to date execpt for ....". Nobody here knows what you need as well as you do, so do your work first and we will gladly help with the rest.

I hope this helps.

bakunin

Here is what i am trying

current_day=$(date +%e)
current_time=$(date +"%H:%M")
current_month=$(date +"%m")

if [ $current_day == 25 ] && [ $current_time == '10:00' ]
      sh -x script_1.sh && break  
 fi

if [ $current_time == '10:00' ]
then
   sh -x script_2.sh
fi

if [ $current_month == 4 ] || [ $current_month == 8 ] || [ $current_month == 12 ]
then 
  if [ $current_day == 30 ] && [ $current_time == '10:00' ]
    then
      sh -x script_3.sh
  fi
fi


For instance if my script_1 fails on 25th and trying to re-run the main_script.sh on next day, then it should run only script_1.sh instead of script_2.sh because script_2.sh was already successful on 25th

I don't understand. You want script_1 to run on the 25th. But if it fails you want it to run on the 26th?

You want script_2 to run every day. But if it succeeds on the 25th you don't want it to run on the 26th?

What if script_1 keeps failing?

Andrew

Let me explain you clearly. The expectation of script_1 - every month 25th it would run. Script_2 - every day and script_3 every quarterly month end. For eg. if script_1 fails due to any reason on 25th and if i re-run the main_script on 26th. In this scenario script_1 will not run on 26th but i would like to run on 26th because it failed on 25th but i tried re-running on next day or any other day on same month, if i re-run the main_Script for that month then it should script_1 should run. In this scenario if i take script_2 which runs every day shouldn't run for again because it was already successful on 25th daily run

Comments:
break breaks a current for-loop or while-loop. exit exits the script.
&& runs the following command after a good exit status. || runs the command after a bad exit status.
If the exit status of the previous run matters, you need to save this somehow in a file, to be discovered in the next run.
date +%e puts a leading space if day is less than 10. date +%d returns the plain decimal number.
Why check the current time? Why not simply schedule for 10:00 (daily at 10:00) in crontab?

Expanding a little on what MadeInGermany has already said...

Do you realize that there are 4 quarters in a year; not 3? Do you also realize that month numbers 4 and 8 are not the last month in any calendar quarter?

Are you aware that break has undefined behavior if it is invoked when you are not inside a for , while , or until loop? Although it is treated as a no-op by the Korn shell, it will give you a syntax error in bash .

What operating system (including version) are you using?

What shell (including version) are you using?

What exit code does script1.sh return when it succeeds. What exit codes does script1.sh return when it fails?

What exit code does script2.sh return when it succeeds. What exit codes does script2.sh return when it fails?

What exit code does script3.sh return when it succeeds. What exit codes does script3.sh return when it fails?

Even if you use cron to start your script, do you realize that there is no guarantee that any job will be started within one minute of its scheduled start time?

Hi Don,

Its bash and Linux flavour,

for success scenario it will not return any exit because there will be scenario where daily and 25th will come in same time.

If the script_1.sh fails then it should exit post script_2.sh completes

Your answers above demonstrate a complete lack of understanding of how running commands in your main script works, how all three of the scripts invoked by your main script work, and how shell programming works.

All of the actions taken in your main script are run synchronously, so there is absolutely no chance that if script_1.sh fails (or if it succeeds) it will not exit before script_2.sh starts. But, of course, if the command in your main script:

current_time=$(date +"%H:%M")

is invoked at any time other than the first minute of 10 o'clock in the morning, none of your numbered scripts will ever be run anyway. I see no reason why this test should be included in your script nor anything in the description of your problem that would make such a test desirable. Every command that is run synchronously returns an exit code before the next command in your script starts. Always. Unconditionally.

If you can't figure out whether or not any of the shell scripts you are invoking in your main script succeeded, there is absolutely no way that you can record whether or not they succeeded so you can re-run them the next day if they failed.

You can save the exit status in a variable

./script1
x1=$?
./script2
if [ $x1 -ne 0 ]
then
  echo "script1 failed with status $x1"
  exit $x1
fi
./script3

If you want to force the main script to run script_1 learn about getopt/getopts and put in a flag to force the running of script_1:

force_script1="false"
while getopts f optName
do
   case "$optName" in
      f) force_script1="true" ;;
      *) ;; # just ignore for now
   esac
done
shift $((OPTIND - 1))

Now if the date is not the 25th you check to see whether ${force_script1} is set to "true" (the string, not the boolean).
I don't understand why you don't want to run script_2 if you are having to rerun script_1. It's a different day; you are running script_2 daily. Right? Unless the main script is being run daily from cron?

And there is this:

which implies that script_2 should not run EVER on the 26th because it ran successfully on the 25th!

Andrew