I want to process each stdout-line for a shell, the moment it is created. I want to grab the output of test.sh (a long process). My current approach is this:
./test.sh >tmp.txt &
PID=$!
tail -f tmp.txt | while read line; do
echo $line
ps ${PID} > /dev/null
if [ $? -ne 0 ]; then
echo "exiting.."
fi
done;
But unfortunately, this will print “exiting” and then wait, as the tail -f is still running. I tried both break and exit
I run this on FreeBSD, so I cannot use the --pid= option of some linux tails.
I can use ps and grep to get the pid of the tail and kill it, but thats seems very ugly to me.
Any hints?
why do you need the
tailprocess?Could you instead do something along the lines of
or, if you want to keep the output in tmp.txt :
If you still want to use an intermediate
tail -fprocess, maybe you could use a named pipe (fifo) instead of a regular pipe, to allow detaching thetailprocess and getting its pid:I should however mention that such a solution presents several heavy problems of race conditions :
test.shcould be reused by another process;test.shprocess is still alive when you read the last line, you won’t have any other occasion to detect its death afterwards and your loop will hang.