16

I know that well-behaved utilities like grep output "normal" messages to stdout, and error messages to stderr.

$ grep '^foo' file1 file2
file1:foo
grep: file2: No such file or directory

When I'm writing shell scripts myself I often find it hard to decide what output and which messages I should present on stderr, or if I should bother at all.

I'd like to know about good practice: When is redirecting some message to stderr called for and reasonable, and when not?

"It depends", sure, but do you have some insights that would help me make these decisions?

In order to make this subjective question fit the format, I would like to encourage answers that address the "why", and are informed by experience and if possible backed by facts.

glts
  • 582

3 Answers3

15

When I'm writing shell scripts myself I often find it hard to decide what output and which messages I should present on stderr, or if I should bother at all.

Silence is golden. Output nothing if everything is fine.

I'd like to know about good practice: When is redirecting some message to stderr called for and reasonable, and when not?

The easiest way to separate stderr from stdout : just imagine all your scripts output will be redirected to another command via pipe. In that case you should keep all notifications in stderr, as such unexpected information in stdout may break the pipe sequence.

Also sometimes in pipes like this one:

command1 | while read line ; do command2 ; done | command3

you need pass something from command2 to users output. The easiest way without temporary files is stderr.

rush
  • 27,403
  • Thank you for the "imagine a pipe" idea. Sometimes I have deploy scripts that do nothing but "notify" (echo some variables, show what has been done, show progress). I hesitate to put everything on stderr since these logging messages are all the script will ever output. I'm not sure how to apply the pipe idea in these situations. – glts Jun 13 '13 at 19:25
  • 1
    @glts programs are always getting modified and improved. While the scripts you mention don't output any data now, they might later or you might use them as a starting points for other scripts that do. If you follow the convention to start with, you'll get a lot less surprises later. OTOH, if you just want to save the output to a file, then you have to redirect stderr, so it's a tradeoff like everything else. – Joe Jun 14 '13 at 23:01
  • +1 Another paraphrase: make sure stdout is always machine readable, or at least contains useful textual data in a consistent format. – tripleee Aug 11 '13 at 21:51
3

I generally write everything that relates to the application operation to stderr, stdout is reserved for data.

Imagine an application like cat. When you use it to read input and pass it to another application (via a pipe), you don't want the output to be littered with status messages.

Everything that might be interesting to another application or a postprocessor to my application is going to stdout, everything that only relates to the interna of my application is going to stderr.

0

My personal preference is to send error messages and exceptions to stderr and informational messages to stdout. IMO, stderr is for any exceptions and hence, my convention.

unxnut
  • 6,008