(Possibly related to Do some programs not accept process substitution for input files?)
In some Bash unit test scripts I'm using the following trick to log and display stdout and stderr of a command:
command > >(tee "${stdoutF}") 2> >(tee "${stderrF}" >&2)
This process produces some output to stdout, so the $stdoutF file gets some data. Then I run another command which does not output any data:
diff -r "$source" "$target" > >(tee "${stdoutF}") 2> >(tee "${stderrF}" >&2)
However, it doesn't look like this process always finishes successfully before the test for emptiness is run (using shunit-ng):
assertNull 'Unexpected output to stdout' "$(<"$stdoutF")"
In a 100 run test this failed 25 times.
Should it be sufficient to call sync before testing the file for emptiness:
sync
assertNull 'Unexpected output to stdout' "$(<"$stdoutF")"
... and/or should it work by forcing the sequence of the commands:
diff -r "$source" "$target" \
> >(tee "${stdoutF}"; assertNull 'Unexpected output to stdout' "$(<"$stdoutF")")
2> >(tee "${stderrF}" >&2)
... and/or is it possible to tee it somehow to assertNull directly instead of a file?
Update: sync is not the answer - See Gilles' response below.
Update 2: Discussion taken further to Save stdout, stderr and stdout+stderr synchronously. Thanks for the answers!