Search code examples
pythonlinuxbashterminalcron

running the program after it terminates using cron


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


Solution

  • 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.