If I run
$#/bin/bash
for i in `seq 5`; do
exec 3> >(sed -e "s/^/$i: /"; echo "$i-")
echo foo >&3
echo bar >&3
exec 3>&-
done
then the result is not synchronous; it could be something like:
1: foo
1: bar
2: foo
2: bar
1-
3: foo
3: bar
2-
3-
4: foo
5: foo
4: bar
5: bar
4-
5-
How do I ensure that the process substitution >(...)
is completed before proceeding to the next iteration?
Inserting sleep 0.1
after exec 3>&-
helped, but it's inelegant, inefficient, and not guaranteed to always work.
EDIT: The example may look silly, but it was for illustration only. What I'm doing is reading a stream of input in a loop, feeding each line to a process which occasionally changes during the loop. Easier explained in code:
# again, simplified for illustration
while IFS= read line; do
case $line in
@*)
exec 3>&-
filename=${line:1}
echo "starting $filename"
exec 3> >(sort >"$filename"; echo "finished $filename")
;;
*)
echo "$line" >&3
;;
esac
done
exec 3>&-