How to tell if output of a command or shell script is stdout or stderr

There's no way to tell once the output has already been printed. In this case, both stdout and stderr are connected to the terminal, so the information about which stream was written to was already lost by the time the text appeared on your terminal; they were combined by the program before ever making it to the terminal.

What you can do, in a case like the above, would be to run the command with stdout and stderr redirected to different places and see what happens. Or run it twice, once with stdout redirected to /dev/null and once with stderr redirected to /dev/null, and see which of those cases results in the text showing up.

You can redirect stdout to /dev/null by tacking >/dev/null on the end of the command line, and you can redirect stderr to /dev/null by adding 2>/dev/null.


You can redirect stdout using > file, and redirect stderr using 2> file. Many modern shells support redirecting to commands, so you can use sed to highlight which output comes from which stream:

$ ls 2> >(sed 's/^/2: /') > >(sed 's/^/1: /')
1: unity_support_test.0
1: vmwareDnD

$ ls foo 2> >(sed 's/^/2: /') > >(sed 's/^/1: /')
2: ls: cannot access foo: No such file or directory

The annotate-output script from Debian's devscripts lets you do this selectively:

$ annotate-output ls -ld /test
14:54:22 -: Started ls -ld /test
14:54:22 E: ls: cannot access /test: No such file or directory
14:54:22 -: Finished with exitcode 2

The second column indicates stdout and stderr with O and E respectively.

There are some caveats, the main one being as noted in the other answers: you can't do this after the fact. Neither the shell nor the terminal are aware of how an arbitrary program uses its file descriptors, though the shell is responsible for setting them up initially.

This method uses fifos, writing to a fifo can behave differently than writing to a tty, and writing to two different fifos is definitely different (potential timing/interleaving issues). Also, it's not suitable for interactive use, e.g. annotate-output bash is not a great plan, but it's useful for many other purposes. There are many, many examples of scripts and shell functions in answers to related questions about colorising stdin/stdout/stderr, the most robust is stderrd which uses runtime modification of (most) programs to modify data written to stderr.

This question that Anko links to has good answers on that related theme: colorising the stdout/stderr output: Can I configure my shell to print STDERR and STDOUT in different colors?