sending output to /dev/stderr vs. >&2
The special device /dev/stderr
is system-specific, while the file descriptor 2
(not the special device /proc/self/fd/2
) is portable. If you want to write non-portable code, those special devices are a good place to start.
There are a few systems with /dev/stderr
: Linux, of course, and OSX. But OSX has no /proc
filesystem, and its /dev/stderr
is a link to /dev/fd/2
.
Further reading:
- Portability of “> /dev/stdout”
- What method should I use to write error messages to 'stderr' using 'printf' in a bash script?
- patches/awk-dev-stderr (autoconf-patches)
- Redirect stderr and stdout in a Bash script
- Chapter 20. I/O Redirection (Advanced Bash-Scripting Guide)
In bash, and other shells, the way to redirect something to standard error is to use >&2
. Bash opens /dev/stderr
as the file descriptor 2
. File descriptors are referenced by &N
where N
is the number of the descriptor. So, echo error >&2
will print error
to standard error, to /dev/stderr
.
It will also open /dev/stdout
as file descriptor 1
. This means you can do echo output >&1
. However, since everything is printed to standard output anyway by default, that is the same as echo output
by itself.
Now, 2>
is different. Here, you are redirecting the error output of a command somewhere else. So, 2>file
means "redirect anything printed to file descriptor 2 (standard error) to file
".
You're right, >&2
is more direct and perfectly "idiomatic". They should be equivalent, so there's no particular reason to use >/dev/stderr
. Except that, if someone reading doesn't know what these do, one of them is probably easier to find out than the other :-). But in general I'd suggest you use >&2
.
/dev/stderr could be useful when programs will write errors to a specified filename, but don't support stderr. Clearly this is a bit contrived; /dev/stdout is much more useful. (I recently found the mysql_safe
wrapper script won't write errors to the console; unfortunately it also wants to change the permissions on the error log file, so using /dev/stderr causes a few superfluous warnings).