How to have “say” wait when used in a series of pipes

bashcommand lineterminal

I'm trying to figure out how to be notified that multiple stages have been reached in a series of piped commands.

For the sake of discussion, lets say I have a command like so that any part of it could take a long time. I want to be notified when each "stage" has completed by having the script say something.

netstat -a | stage_complete.sh "netstat" | grep -v WAIT | stage_complete.sh "grep done"

where stage_complete.sh is a simple bash script to say the argument text, and pass stdin to stdout.

stage_complete.sh

OUT=$*
say "$OUT"
cat /dev/stdin

This idea works fine – except that say doesn't "wait" for the word to complete – it just starts to say the phrase, and then immediately continues on, so if my commands run quickly, then it says "netstat" and "grep done" at the same time, overlapping each other.

How can i make say wait? or have it queue up text, and only say it once the previous text has completed? Note that I've noticed that commands like so wait for each other to complete:

say one && say two && say three

but can't see how to make that work in my pipes!

Best Answer

Turns out all I had to do was consume all of stdin at the start of my script... I don't want it to process stdin as it's received, but when the entire previous command in the pipe chain completes.

So my stage_complete.sh script is simply this, which works for my use case!

stage_complete.sh

#!/usr/bin/env bash

OUT=$(cat -)

MSG="$*"
say "$MSG"

echo "$OUT"

Note: I figured this out by asking the question in another stack exchange (unix), over here