13

Is there a guideline when to use the error when writing a command-line application? To my surprise, I didn't find anything when googling it.

In particular, the question I'm concerned with right now is whether to use stdout or stderr when the user called the program with illegal arguments. However, a more comprehensive answer is very much appreciated because this surely won't be the only case in which a clear rule is needed to write a program which behaves in the way it's expected to by the user.

Kusalananda
  • 333,661
UTF-8
  • 3,237
  • Is it okay for those error messages to get mixed in with the regular output? E.g. is the program a filter for data? – thrig Jan 12 '17 at 21:42
  • It isn't a filter for data. It's also not interactive. The user calls it with arguments (among which are file paths), the programs works, changes those files, prints a few messages, ideally doesn't print any error messages, and terminates. – UTF-8 Jan 12 '17 at 22:09

2 Answers2

19

Yes, do display a message on stderr when the wrong arguments are used. And if that also causes the application to exit, exit with non-zero exit status.

You should use the standard error stream for diagnostic messages or for user interaction. Diagnostic messages include error messages, warnings and other messages that are not part of the utility's output when it's operating correctly ("correctly" meaning there is nothing exceptional happening, like files not being found, or whatever it may be).

Many shells (all?) display prompts, what the user types, and menus etc. on stderr so that redirecting stdout won't stop you from interacting with the shell in a meaningful way.

The following is from a blog post on this topic:

This is a quote from Doug McIllroy, inventor of Unix pipes, explaining how stderr came to be. 'v6' is referring to a version of specific version of the original Unix operating system that was released in 1975.

All programs placed diagnostics on the standard output. This had always caused trouble when the output was redirected into a file, but became intolerable when the output was sent to an unsuspecting process. Nevertheless, unwilling to violate the simplicity of the standard-input-standard-output model, people tolerated this state of affairs through v6. Shortly thereafter Dennis Ritchie cut the Gordian knot by introducing the standard error file. That was not quite enough. With pipelines diagnostics could come from any of several programs running simultaneously. Diagnostics needed to identify themselves.
-- Doug McIllroy, "A Research UNIX Reader: Annotated Excerpts from the Programmer’s Manual, 1971-1986"

To "identify oneself" means simply saying "Hey! It's me talking! This went wrong: [...]":

$ ls nothere
ls: nothere: No such file or directory

Doing this on stderr is preferable, since it could otherwise be read by whatever was reading on stdout (but we don't do that with ls anyway, do we?).

Kusalananda
  • 333,661
  • So when you ask the user something as the application is running, you should print the question on stderr? That doesn't sound right. Do you have a source for it? Does this only apply to applications which have output other than just questions and responses (output the user might want to pipe somewhere)? – UTF-8 Jan 12 '17 at 22:14
  • @UTF-8 Should the text of the question be considered part of the output of the program? What about that which the user types in? I don't think it should be (just like shells don't think it should be). But maybe it depends on the application? – Kusalananda Jan 12 '17 at 22:17
  • 1
    Thank you for your edit. In the meantime, I checked the behavior of standard applications and they behave like one would expect them to behave after reading your answer. – UTF-8 Jan 12 '17 at 22:23
  • @UTF-8 you might find this Q&A relevant: http://unix.stackexchange.com/q/331611/22222 – terdon Jan 12 '17 at 22:39
7

From POSIX specifications for the standard streams:

At program start-up, three streams shall be predefined and need not be opened explicitly: standard input (for reading conventional input), standard output (for writing conventional output), and standard error (for writing diagnostic output).

In other words, errors, debugging info, and anything that falls into diagnostic category goes into stderr.

See related question for more info: Do progress reports/logging information belong on stderr or stdout?