Do not close stderr

April 22nd, 2008

A few years ago, I wrote a post commenting on how ugly this was:

$ someprog 2>/dev/null

I was nearly imploring the reader to close stderr:

$ someprog 2>&-

Some very knowledgeable anonymous commenter explained why that was a bad idea. At the time, I didn’t understand exactly what they were saying. As such, I deleted the post. Yesterday, for no particular reason, the implications of closing stderr popped into my head. In the shower no less.

I wrote a simple little C program named do-not-close-stderr.c. It takes two parameters, a string you want written to a file and the file you want said string written to. After opening the file, it prints “some kind of warning message” to stderr. Here we are:

$ gcc -Wall do-not-close-stderr.c -o do-not-close-stderr
$ ./do-not-close-stderr "Brock was here." output
Some kind of warning message.
$ cat output
Brock was here.

Now lets close standard error when executing:

$ ./do-not-close-stderr "Brock was here." output 2>&-
$ cat output
Some kind of warning message.
Brock was here.

Thanks to whoever that commenter was.

7 Responses to “Do not close stderr”

  1. Naveed Says:

    Whoa, it seems like stderr was redirected to stdout since stderr was closed. Is that what happened?

  2. forcey Says:

    That’s really the case. The reason is that stderr is opened with fd=2 by default, and if you close it, the file descriptor you open next will be 2. And if you or some external program you called by system() produces error message to ’stderr’ - your file would be corrupted. It actually happened to me. If you don’t want your program to show error messages on the screen, please reopen stderr to somewhere else, rather than close it.

  3. Brendan Miller Says:

    Cool, but since you’re using ansi c streams as opposed to unix file io isn’t this a bug in glibc? Shouldn’t glibc be checking to see if the file descriptor is open before fdopening file descriptor 2?

  4. Brock Noland Says:

    Naveed: Is that what happened?

    Yep.

    Brendan Miller: Cool, but since you’re using ansi c streams as opposed to unix file io isn’t this a bug in glibc? Shouldn’t glibc be checking to see if the file descriptor is open before fdopening file descriptor 2?

    I am 99.9% sure UNIX file io would do the same thing.

  5. Noname Says:

    Than the logical solution is 2>/dev/null ?

  6. Brock Noland Says:

    Yep.

  7. Noname Says:

    Which has started the whole ordeal as an uglu and a bad thing … :)

Leave a Reply

If Wordpress eats your comment (shell output, loops, ex..) email the text to me.