Breaking "while read" also breaks the parent process

Hi,

I'm a bit confused. Maybe some master can explain to me what is happening.

I have a program that starts issuing output about himself loading.
I want to run it in another thread but I want to wait untill it's fully loaded.

Program sample:

$ cat myprogram
echo "loading"
echo "almost ready"
echo "up and running"
while true; do
    echo "I don't care about the rest of the output"
    sleep 1
done

If I run it like this, it will stay in another thread but I will not be sure it is "up and running":

$ myprogram &

So I tried to run it like this but the process dies very soon :

$ myprogram | while read -r; do
    [[ "$REPLY" == "up and running" ]] && break
done
echo "Now I know myprogram went all the way untill it is up and running"
echo "But now myprogram is dead :-("

Question: How can I stat myprogram and wait untill it outputs "up and running"?

Thanks for your help.
Santiago

The reason your program is breaking is that the break will exit the loop, ending the read, which sends a SIGPIPE to myprogram, which usually is an exit condition.

Do you have influence on the code of the program being started? If so, have it create a file once it's done, for which you can wait.

If not you'll have to put the reading loop into the background, and have it signal the main program once it's done. Something like

#!/bin/sh

waiting=1
ppid=$$

trap waiting=0 USR1

(
  ./myprogram | while read -r
  do
    [[ "$REPLY" == "up and running" ]] && kill -USR1 $ppid
  done
) &

printf "Waiting for startup"
while [ $waiting -eq 1 ]
do
  printf '.'
  sleep 1
done
echo

: # Stuff to be done here

wait #Wait for "myprogram" to exit

Thanks pludi, I love your answer which is fairly new to me.
So basically you do:

trap waiting=0 USR1

Which I guess means: "waiting becomes 0 as soon as the signal USR1 is received"
And then you do:

kill -USR1 $ppid

Which I guess means: "Send signal USR1 to the process"
Can you confirm?
I read through man kill and I still have one question?
Are you strictly limited to the list of signals mentioned in the man page?
What makes you choose USR1?
I guess you need a safe signal that would not be easily used by other processes.

Thanks for your help
Santiago

Yes, that's about correct.

As for the signals, one is pretty much limited to the signals reported by "kill -l", minus a few. For example, SIGKILL can't be trapped. And for shell scripts there's the additional signal 0, which is triggered whenever the script exits (great for cleanup).

USR1 and USR2 are intended for use for IPC, as they have no fixed meaning. Other typical uses are SIGHUP (HangUP) to tell daemons to reinitialize themselves without restarting, SIGINT for catching ^C, or SIGWINCH when the terminal window was resized.