Error Not Error
I stumbled on a piece of my old code of some CLI utility and remembered what a mess my unawareness of this specificity of UNIX streams caused (I'm not sure if it applies to Windows).
This is really counterintuitive, but the stderr
UNIX stream is not only for errors. It is for everything except the main result of a program.
- Want to print debug information? Send it to
stderr
. - Want to ask for a confirmation? Send it to
stderr
. - Want to print a progress report? Send it to
stderr
. - Want to print a non-critical warning? Send it to
stderr
. - Want to print an error? Send it to
stderr
.
The only case when you should print to stdout
is when you have the final result of your program, and only this result should go there.
For example, if your program performs a file search, a list of the found files should go to stdout
.
If your program uploads specified files to a server and you want to print an informational message that all files were successfully uploaded, it should go to stderr
.
Why? Because users of your program should be able to pipe the results.
Let's say you built a CLI program answer
that answers the "ultimate question of life, the universe, and everything" (in Rust, of course).
println!("42"); // the main result, prints to stdout
eprintln!("Answered!"); // informational message, prints to stderr
When you run it and pipe the results to pbcopy
(a macOS utility that puts data into the clipboard):
answer | pbcopy
In your terminal, you will see:
Answered!
But in your clipboard, there will be 42
. Because pbcopy
received data from the stdout
of your program via its stdin
and placed it into your clipboard.