How to set font color for STDOUT and STDERR

Viewed 32326

I want to differentiate the STDOUT and STDERR messages in my terminal. If a script or command is printing a message in terminal I want to differentiate by colors; is it possible?

(E.g. stderr font color is red, and stdout font color is blue.)

Example (using bold):

$date
Wed Jul 27 12:36:50 IST 2011

$datee
bash: datee: command not found

$alias ls
alias ls='ls --color=auto -F'

$aliass ls
bash: aliass: command not found

8 Answers

Expanding on the answer @gospes gave, I added the functionality to print out partial lines without waiting for a newline, and some comments. Allows for better output from wget or typing in a interactive shell.

exec 9>&2
exec 8> >(
    while [ "$r" != "1" ]; do
        # read input, no field separators or backslash escaping, 1/20th second timeout
        IFS='' read -rt 0.05 line
        r=$?
        # if we have input, print the color change control char and what input we have
        if ! [ "${#line}" = "0" ]; then
            echo -ne "\e[1;33m${line}"
        fi
        # end of line detected, print default color control char and newline
        if [ "$r" = "0" ] ; then
            echo -e "\e[0m"
        fi
        # slow infinite loops on unexpected returns - shouldn't happen
        if ! [ "$r" = "0" ] && ! [ "$r" = "142" ]; then
            sleep 0.05
        fi
    done
)
function undirect(){ exec 2>&9; }
function redirect(){ exec 2>&8; }
trap "redirect;" DEBUG
PROMPT_COMMAND='undirect;'

I used bold yellow (1;33) but you can replace it with whatever, red for example (31) or bold red (1;33), and I arbitrarily chose 0.05 seconds for re-checking for end-of-lines and pausing on unexpected return codes (never found any); it could probably be lowered, or possibly removed from the read command.

You can make use of grep for this. Note that this assumes that grep is configured to have coloured output (this is the default on many systems).

$ aliass ls 2> >(GREP_COLORS='ms=01;31' grep .) 1> >(GREP_COLORS='ms=01;32' grep .)
aliass: command not found

This is a little long winded, if you are simply wanting to distinguish stderr fromstdout you can simply do this:

$ (echo "this is stdout"; echo "this is stderr" >&2) | grep .
this is stderr
this is stdout

This will result in stdout being highlighted with the default grep colour and stderr being white.

This might be the opposite of what you want if your default grep colour is red. If so you can explicitly set the grep colour to green:

$ GREP_COLORS='ms=01;32'
$ (echo "this is stdout"; echo "this is stderr" >&2) | grep .

If you explicitly want to get red output for stderr:

$ GREP_COLORS='ms=01;31'
$ (echo "this is stdout"; echo "this is stderr" >&2) 2> >(grep .)

Note that this solution will not preserve the output order.

Related