0

I need to set a program in cron which is set in such a way that it restarts everytime the program is terminated

why do i want to do this job?

The program is actually extracting information from a website using web scraping and it terminates when it reaches the point where the information is up-to- date
This the part of the python code

    sql = """SELECT Short_link FROM Properties WHERE Short_link=%s"""
            rows = cursor.execute(sql,(link_result))
            print rows
            if rows>=1:
                print "Already present"
                sys.exit()
            else:
        query="""INSERT INTO Properties (Published_Date, Title,Price,Bedroom,Agency_Fee, Bathroom, Size,Prop_ref,Furnished_status,Rent_payment,Building_info,Amenities,Trade_name,Licence, RERA_ID,Phone_info,Short_link) values (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"""
        cursor.execute(query,(date_result, title_result, price_result, bedroom_result, agencyfee_result, bathroom_result, size_result, propertyref_result, furnished_result, rent_is_paid_result, building_result, Amenities_result, tradename_result, licencenum_result, reraid_result, phone_result, link_result))

The script is as follows: run.sh

#!/bin/bash
    PATH=$PATH:/bin:/usr/bin
    
    date +'%H:%M:%S Started' >> /home/ahmed/Desktop/log.txt
    
    TMP_FILE=/tmp/i_am_running
    [ -f $TMP_FILE ] && exit
    touch $TMP_FILE
    
    date +'%H:%M:%S Starting Python' >> /home/ahmed/Desktop/log.txt
    /usr/bin/python /home/ahmed/Desktop/python.py
    rm $TMP_FILE
    
    date +'%H:%M:%S Ended' >> /home/ahmed/Desktop/log.txt

The cron command i am using is * * * * * /home/ahmed/Desktop/run.sh

The log file is as follows:

15:21:01 Started
15:21:02 Starting Python
15:22:02 Started
15:23:01 Started
15:24:01 Started
15:24:30 Ended
15:25:01 Started
15:25:01 Starting Python
15:26:01 Started
15:27:18 Started
15:28:01 Started
15:29:01 Started
15:30:01 Started
15:31:01 Started
15:31:16 Ended
15:32:01 Started
15:32:01 Starting Python
15:33:01 Started
15:34:01 Started

It seems like the program is restarted before its ended. the log file should have starting program, started, ended, starting program, started, ended and so on.

Can someone guide me please? perhaps there are some changes need in the bash script? how can i set the program to starting, started, ended and so on

user3265370
  • 121
  • 1
  • 2
  • 12
  • Do you want to make sure that Cron does not execute `run.sh` if its still running or is `run.sh` intended to ensure that `python.py` does not run more than once simultaneously? – Phillip Mar 24 '14 at 12:40
  • Consider checking for PID by name with an IF NOT query prior to running the script again or slowing the cron calls down to every three or five minutes if acceptable. – zedman9991 Mar 24 '14 at 12:42
  • The run.sh is made to run the program everytime the python program is ended. to be honest it is made by someone else and according to him he answered as follows http://stackoverflow.com/questions/22554572/bash-program-in-cron-that-runs-everytime-the-program-is-terminated/22555757?noredirect=1#comment34329881_22555757 – user3265370 Mar 24 '14 at 12:44
  • That's already what's happening. The log might be misleading: "Started" only means that `run.sh` was callled. The python script is only called when you see "Starting Python". – Phillip Mar 24 '14 at 12:47
  • alright then. so u mean started means an attempt to call the python program but it actually doesnt start the program but just call it. its only called when i see starting python. is this what you are saying – user3265370 Mar 24 '14 at 12:51
  • If you want to run a particular program based on a trigger that is not the current system time, then I would suggest that `cron` is not the right tool for the job... – twalberg Mar 24 '14 at 15:03

2 Answers2

0

You may use another shell script to run you own run.sh. For example

$ cat runner.sh
while [ 1 ]; do
    ./run.sh
    if [ -e /tmp/stop_run ]; then
       exit
    fi
    sleep 1
done

If you need to stop this script, just touch /tmp/stop_run than kill the run.sh.

You don't need cron for this solution. Just add runner.sh to /etc/rc.local

0

The program is restarted before it ends because you are running the cron job every minute of every hour of every day...

* * * * * /home/ahmed/Desktop/run.sh

What you need to do is a infinite loop to run the program until it finishes and start running again when the loop finishes. Running the program every minute is only ok when you know that the task is not gonna take longer than a minute.

So I would do:

while(true){

    PATH=$PATH:/bin:/usr/bin

    date +'%H:%M:%S Started' >> /home/ahmed/Desktop/log.txt

    # TMP_FILE=/tmp/i_am_running # Don't need this
    # [ -f $TMP_FILE ] && exit # (Don't need to check if a the script is running)
    # touch $TMP_FILE # (You don't need to create the file)

    date +'%H:%M:%S Starting Python' >> /home/ahmed/Desktop/log.txt
    /usr/bin/python /home/ahmed/Desktop/python.py
    # rm $TMP_FILE # (I commented this as you don't need it)

    date +'%H:%M:%S Ended' >> /home/ahmed/Desktop/log.txt

    # You can add a 'sleep XX' to delay the script between executions in case you don't 
    # want it to be executed one time and another as soon as an execeution finishes.
    # Remember to comment (add '#') or remove the line of cron (crontab -e)

}

What you are doing is running an instance of the program every minute but they will only finish after running the time it takes:

15:21:01 Started (Start 1st program)
15:21:02 Starting Python (python script is executed, called from bash script)
15:22:02 Started (cron runs 2nd program, not execute python, exit)
15:23:01 Started (cron runs 3rd program, not execute python, exit)
15:24:01 Started (cron runs program, not execute python, exit)
15:24:30 Ended (End 1st program)
15:25:01 Started (cron runs 5th program)
15:25:01 Starting Python (execute 5th program's python script, called from bash script)
15:26:01 Started (etc..)
15:27:18 Started
15:28:01 Started
15:29:01 Started
15:30:01 Started    
15:31:01 Started
15:31:16 Ended
15:32:01 Started
15:32:01 Starting Python
15:33:01 Started    
15:34:01 Started

As I told you the best way in your case is the infinite loop. However if you still prefer cron (which I personally like, since infinite loops aren't always the best option, you can always set up cron to execute your script every 10, 15, or 20 minutes which is a better choice.

*/10 * * * * /home/ahmed/Desktop/run.sh # This will exceute every 10 minutes
*/15 * * * * /home/ahmed/Desktop/run.sh # This will exceute every 15 minutes
  • Remember that if you choose cron, you will need to uncomment and keep the lines that check for the file (if file exists means program is still executing). But it's not probable that two executions will step each other since the whole bash script (including python's) takes like 3-4 minutes. With a 10 minute difference, it's enough.
ederollora
  • 1,165
  • 2
  • 11
  • 29
  • to be clear, by your program, you meant the python program or the sh script? – user3265370 Mar 24 '14 at 13:22
  • the sh program, since you are locking the sh script checking the file that you create, you are not executing the python but If I were you I woould not use this cron example, as I told you a loop wpuld be e btter approach. – ederollora Mar 24 '14 at 13:34
  • added and developed my answer. Any doubt you have please tell. – ederollora Mar 24 '14 at 17:35