10

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 ?

12

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:

  • 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. – larkey Apr 4 '16 at 8:50
5

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

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.