2

I have a shell script that just calls a Python file in loop e.g.:

for i in $(seq $start_index $end_index)
do 
    python my_script.py
done

The Python process halts when it is not able to generate random numbers in certain ranges.

I am trying to restart the script when it has not printed out to the console for say 30 seconds, else it can keep running.

This is not a cron job which needs to necessarily restart in a fixed interval.

However, a watchdog kind of job that can track would be ideal; but I did not find anything that tracks when was the last output printed.

We could also direct the output from script.sh > log.txt and check for when was the file last modified, but didn't find an elegant way of doing that.

Any help/pointers would be appreciated.

  • Can you explain what you try to do with yr 4 line code snippet at top of post ? You are generating $((end_index - start_index + 1)) processes, each of them running my_script.py. Said processes are all launched in the (very little) time it takes to parse the sequence of indices in yr for loop. That means that all processes will most likely coexist . Is that what you want ? – Cbhihe Oct 12 '19 at 8:36
0

As I manage to construe from OP:

  • you launch process my_script.py, but you can't predict termination or exit time.
  • process my_script.py executes and writes to a log file (call it file.log until it stops.
  • every small time interval, you want check whether the last modification time of your log file is older than 30s. If it is, kill and re-launch process my_script.py

There are various ways of doing this. One of them is to rely on inotify from the inotify-tools package to monitor filesystem's events, along the line of the perfectly good answers here and (better yet) there.

An alternative to the above is to manually detect last modification date for log file and to check whether the pid of your process continues to show. Put all the logic in a short executable bash script, like so:

#!/bin/bash

/usr/bin/python my_script.py >> file.log & # launch process in background
my_proc_pid="$!" # save process pid for last executed command

prevtime=0  # initialize "previous modification time" variable

while : ; do
    sleep 1    # check log file modification time every 1s
    # modification time in milliseconds
    if (( $(\find /path/to/file.log/ -name file.log -printf "%T") - prevtime > 30000)); then
    #if (( "$(\ls -l --time-style=+%s /path/to/logfile/file.log | cut -d' ' -f6)" - prevtime > 30)); then 
        prevtime="$(\find /path/to/file.log/ -name file.log -printf \"%T\")"
        #prevtime="$(\ls -l --time-style=+%s /path/to/logfile/file.log | cut -d' ' -f6)"
        if (\ps | grep -v grep | grep "$my_proc_pid" &>/dev/null) ; then
            # kill process in background, '&>' same as '>/dev/null 2>&1' 
            /usr/bin/kill -9 "$my_proc_pid" &>/dev/null
        fi
        # launch process and save its pid
        /usr/bin/python my_script.py >> file.log & 
        my_proc_pid="$!"
    fi
done

# use CTRL-C to stop loop execution and to exit script

Note: I included two ways of looking up the modification time of your log file. The one that is not commented out involves find which handles strange file names (e.g. with spaces, etc) better than ls and does not rely on any pipe. In that case, you must however provide the complete PATH to your log file (/path/to/logfile/) as the first argument to the cmd find. In the case of ls, you need to provide same path, along with the complete logfile's filename, as in: /path/to/logfile/file.log

I tested this partially on bash v5.0.1. Report issues if any. HTH

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.