Marc Herbert wrote: > What is wrong with the following: > > prefix_with_date () > { > while read; do > printf '%s: %s\n' "$(date)" "$REPLY"; > done > } > > seq 4 | prefix_with_date > ls | prefix_with_date
Sorry I missed the fact that you want to run your commands in the current shell. There are no real coroutines in shell. The current shell process does not know how to schedule two pieces of code. So each time two pieces of code communicate through a pipe they have to be run in two *concurrent* processes (typically: subshells). The producer and consumer of a pipe must run independently of each other. Whether you are using process substitution or the more usual and portable pipe "|" does not matter here: you need concurrency. So at least one of: 1. your prefixer code, 2. your unknown command has to run in a independent process, "asynchronous" with the current shell. Since you absolutely want your unknown commands to run in the current shell, then it is your "prefixing" code that has to run in a concurrent process. Now I do not really see any other way to avoid the ugliness of concurrently printing on stdout than to "wait" for your concurrent prefixer to complete, more or less like you did. A variant is to ask socat to handle the cleanup actions for you like this: prefix_with_date() { local P=/tmp/dataorig.$$ socat -u PIPE:${P} SYSTEM:'while read; do echo "$(date):\\ $REPLY"; done' & socatPID=$! until [ -e ${P} ]; do sleep 1; done $@ > ${P} wait $socatPID } prefix_with_date seq 5