sending output to /dev/stderr vs. >&2

9,417

Solution 1

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:

Solution 2

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".

Solution 3

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).

Share:
9,417

Related videos on Youtube

Tam Borine
Author by

Tam Borine

Updated on September 18, 2022

Comments

  • Tam Borine
    Tam Borine over 1 year

    In scripts, errors are usually sent to file descriptor 2 with &2, ie:

    echo "error" >&2
    

    Sometimes /dev/stderr is used instead:

    echo "error" > /dev/stderr 
    

    Looking at /dev/stderr, I see that it is only a symlink to /proc/self/fd/2 , which in turn is a symlink to /dev/pts/5 (on my current terminal).

    Seems little bit over complicated. Is there some logic behind that ?

    Is using /dev/stderr and &2 equivalent ?

    Is any of those preferred over the other ?

  • ljrk
    ljrk about 8 years
    Also there's the case where someone wants to do eg. this 2> bla.log which would work as long as you pipe to 2 and not hard-code /dev/stderr. Basically 2 doesn't need to be the stderr output.