Display stdout and stderr in two separate streams

command lineterminal

I'm looking for a way to visually separate stdout and stderr, so that they don't interleave and so that they can be easily identified. Ideally, stdout and stderr would have separate areas on the screen in which they are displayed, e.g. in different columns. For example, output which would have looked like this:

~$ some command
some useful output info
ERROR: an error
more output
ERROR: has occurred
another message
~$ 

would instead look something like this:

~$ some command          |
some useful output info  |
more output              |  ERROR: an error
another message          |  ERROR: has occurred
~$                       |

Best Answer

You could use GNU screen's vertical split feature:

#! /bin/bash -
tmpdir=$(mktemp -d) || exit
trap 'rm -rf "$tmpdir"' EXIT INT TERM HUP

FIFO=$tmpdir/FIFO
mkfifo "$FIFO" || exit

conf=$tmpdir/conf

cat > "$conf" << 'EOF' || exit
split -v
focus
screen -t stderr sh -c 'tty > "$FIFO"; read done < "$FIFO"'
focus
screen -t stdout sh -c 'read tty < "$FIFO"; eval "$CMD" 2> "$tty"; echo "[Command exited with status $?, press enter to exit]"; read prompt; echo done > "$FIFO"'
EOF

CMD="$*"
export FIFO CMD

screen -mc "$conf"

To use for instance as:

that-script 'ls / /not-here'

The idea is that it runs screen with a temporary conf file that starts two screen windows in a vertical split layout. In the first one, we run your command with the stderr connected to the second one.

We use a named pipe for the second window to communicate its tty device to the first one, and also for the first one to tell the second one when the command is done.

The other advantage compared to pipe-based approaches is that the command's stdout and stderr are still connected to tty devices, so it doesn't affect the buffering. Both panes can also been scrolled up and down independently (using screen's copy mode).

If you run a shell like bash interactively with that script, you'll notice the prompt will be displayed on the second window, while the shell will read what you type in the first window as those shells output their prompt on stderr.

In the case of bash, the echo of what you type will also appear on the second window as that echo is output by the shell (readline in the case of bash) on stderr as well. With some other shells like ksh93, it will show on the first window (echo output by the terminal device driver, not the shell), unless you put the shell in emacs or vi mode with set -o emacs or set -o vi.

Related Question