This is due to row buffering and block buffering. You can control the type of buffering, you can clear them at the point where you want their output to be synchronized, or you can just wait until you exit, and at that moment everything will turn red. If you do not impose it anyway, buffering depends on whether the output is a tty type file descriptor 1 , so redirecting to the channel changes the mode.
In particular:
true false ------------- -------------- $stdout.tty? line-buffered block-buffered $stderr.tty? line-buffered line-buffered
You can configure them the same way with:
$stdout.sync = $stderr.sync = true # or false, of course
My test case:
$stdout.sync = $stderr.sync = true $stdout.puts 'stdout a' sleep 2 $stdout.puts 'stdout b' sleep 2 $stderr.puts 'stderr a' sleep 2 $stderr.puts 'stderr b' sleep 2
1. See Ttyname (3). source share