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