With the following script:
#!/bin/bash
xerr() {
sed -ue "s/^/(stderr) ${FUNCNAME[1]}: /" >&2
}
xlog() {
sed -ue "s/^/(stdout) ${FUNCNAME[1]}: /"
}
main() {
{
sleep 0.25 && echo "ok" &
sleep 1.00 && echo "ok" &
sleep 0.65 && echo "fail" >&2 &
sleep 1.00 && echo "ok" &
sleep 0.65 && echo "ok" &
wait
echo "Finished"
} 2> >(xerr) > >(xlog)
}
main
Background processes finish successfully, but hang forever in wait
:
(stdout) main: ok
(stdout) main: ok
(stderr) main: fail
(stdout) main: ok
(stdout) main: ok
^C
However when (1) not redirecting its output or (2) not running in parallel, all is working as expected:
#(1)
main() {
{
sleep 0.25 && echo "ok"
sleep 1.00 && echo "ok"
sleep 0.65 && echo "fail" >&2
sleep 1.00 && echo "ok"
sleep 0.65 && echo "ok"
echo "Finished"
} 2> >(xerr) > >(xlog)
}
main
#(stdout) main: ok
#(stdout) main: ok
#(stderr) main: fail
#(stdout) main: ok
#(stdout) main: ok
#(stdout) main: Finished
#(2)
main() {
{
sleep 0.25 && echo "ok" &
sleep 1.00 && echo "ok" &
sleep 0.65 && echo "fail" >&2 &
sleep 1.00 && echo "ok" &
sleep 0.65 && echo "ok" &
wait
echo "Finished"
}
}
main
# ok
# fail
# ok
# ok
# ok
# Finished
Is there any reason for this? How can I run processes in parallel and redirect their output at the same time?
CodePudding user response:
Is there any reason for this?
>(xerr)
and >(xlog)
are also background processes; wait
is waiting for (at least one of) them too.
How can I run processes in parallel and redirect their output at the same time?
main() {
{ { {
sleep 0.25 && echo "ok" &
sleep 1.00 && echo "ok" &
sleep 0.65 && echo "fail" >&2 &
sleep 1.00 && echo "ok" &
sleep 0.65 && echo "ok" &
wait
echo "Finished"
} 2>&4 | xlog >&3; } 4>&1 | xerr >&3; } 3>&1
}