Terminate a process using shell script

Hi,

I am writing a shell script to run a process and write the output of the process to a file.

Inside program.sh:
./process.sh > tempfile
..

open tempfile
do the following

But the problem is that process.sh is running indefinitely and program.sh is not executed completely. Can anyone help me to terminate process.sh after the output has been written to the tempfile, so that program.sh can continue its execution.

You have to identify a condition to make sure that process.sh has completed its function. Once that is done, you can star the process.sh in background using & at the end instead of just executing it.

Then you can terminate the process using kill -9 PID

1 Like

Hi,
Thank you for the answer, but the problem is that I should ensure that process.sh is executed only once and only one time value should be entered in the tempfile.(Else it runs infinitely writing values to the tempfile). If I run using

./process.sh > tempfile &
sleep 5
kill -9 $!

There is no way to be determine if write has happened atleast once. Also I cannot determine how long I should wait.

Kindly help me

Hi and welcome to the forum!

How do you know that the process is done writing all the output?
It seems to me that process.sh should finish after it's finished, and i'd try to modify it so that it does. But of course I don't see all the details, so here, this should work on a stubborn process that doesn't know when to leave.
Firstly, to answer my first question, I'd make sure I know when the process.sh is done writing all the output. I'd make it write a unique string that defines the end of writing, e.g. "==DONE WRITING OUTPUT==". Then i could do the following:

#!/bin/bash

out=output.log
: > $out #create the file, or truncate to zero length

./process.sh > $out & #run in the background

pid=$!  #process ID of the neverending process

tail -f $out | while read line ; do #keep reading lines from output
    echo $line | grep  "==DONE WRITING OUTPUT==" &>/dev/null 
    if [ $? -eq 0 ] ; then #grep matched the string
      kill $pid #kill process.sh
    
      tailPID=`ps ax | grep -v grep | grep "tail -f $out" | awk '{print $1}'`
      kill $tailPID #kill tail

      #it's still running here, until end of loop
    fi  
done 

#finish whatever needs to be done

If the process.sh is so stubborn that the 'kill $pid' call won't terminate it, use 'kill -s 9 $pid' instead.

There is quite a lot of killing there, so it deserves some explanation. We have the following processes running:
1) parent script
2) process.sh script running in the background
3) tail -f
4) subshell started by pipe

2) and 3) are killed directly by 'kill $PID' call.
4) is ended by when it reaches the end of loop and receives no more input from (now non-existent) tail
1) continues running until end

If the tail wasn't terminated, this script would hang, refreshing the last lines of unchanging output forever.

I have small doubt here about the logic. If we check for the output file for specific flag like "==DONE WRITING OUTPUT==" It may not be possible to ensure that the process.sh has run only once.

Because if process.sh is running little faster than your shell script, it might add few more rows after starting second run. It is totally situation dependent and it shouldn't be done by this way.

Please post the process.sh script, may be we could find a work around for this.