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?