]> git.proxmox.com Git - rustc.git/blame - src/doc/book/src/ch12-06-writing-to-stderr-instead-of-stdout.md
New upstream version 1.37.0+dfsg1
[rustc.git] / src / doc / book / src / ch12-06-writing-to-stderr-instead-of-stdout.md
CommitLineData
13cf67c4
XL
1## Writing Error Messages to Standard Error Instead of Standard Output
2
3At the moment, we’re writing all of our output to the terminal using the
4`println!` function. Most terminals provide two kinds of output: *standard
5output* (`stdout`) for general information and *standard error* (`stderr`)
6for error messages. This distinction enables users to choose to direct the
7successful output of a program to a file but still print error messages to the
8screen.
9
10The `println!` function is only capable of printing to standard output, so we
11have to use something else to print to standard error.
12
13### Checking Where Errors Are Written
14
15First, let’s observe how the content printed by `minigrep` is currently being
16written to standard output, including any error messages we want to write to
17standard error instead. We’ll do that by redirecting the standard output stream
18to a file while also intentionally causing an error. We won’t redirect the
19standard error stream, so any content sent to standard error will continue to
20display on the screen.
21
22Command line programs are expected to send error messages to the standard error
23stream so we can still see error messages on the screen even if we redirect the
24standard output stream to a file. Our program is not currently well-behaved:
25we’re about to see that it saves the error message output to a file instead!
26
27The way to demonstrate this behavior is by running the program with `>` and the
28filename, *output.txt*, that we want to redirect the standard output stream to.
29We won’t pass any arguments, which should cause an error:
30
31```text
32$ cargo run > output.txt
33```
34
35The `>` syntax tells the shell to write the contents of standard output to
36*output.txt* instead of the screen. We didn’t see the error message we were
37expecting printed to the screen, so that means it must have ended up in the
38file. This is what *output.txt* contains:
39
40```text
41Problem parsing arguments: not enough arguments
42```
43
44Yup, our error message is being printed to standard output. It’s much more
45useful for error messages like this to be printed to standard error so only
46data from a successful run ends up in the file. We’ll change that.
47
48### Printing Errors to Standard Error
49
50We’ll use the code in Listing 12-24 to change how error messages are printed.
51Because of the refactoring we did earlier in this chapter, all the code that
52prints error messages is in one function, `main`. The standard library provides
53the `eprintln!` macro that prints to the standard error stream, so let’s change
54the two places we were calling `println!` to print errors to use `eprintln!`
55instead.
56
57<span class="filename">Filename: src/main.rs</span>
58
59```rust,ignore
60fn main() {
61 let args: Vec<String> = env::args().collect();
62
63 let config = Config::new(&args).unwrap_or_else(|err| {
64 eprintln!("Problem parsing arguments: {}", err);
65 process::exit(1);
66 });
67
68 if let Err(e) = minigrep::run(config) {
69 eprintln!("Application error: {}", e);
70
71 process::exit(1);
72 }
73}
74```
75
76<span class="caption">Listing 12-24: Writing error messages to standard error
77instead of standard output using `eprintln!`</span>
78
79After changing `println!` to `eprintln!`, let’s run the program again in the
80same way, without any arguments and redirecting standard output with `>`:
81
82```text
83$ cargo run > output.txt
84Problem parsing arguments: not enough arguments
85```
86
87Now we see the error onscreen and *output.txt* contains nothing, which is the
88behavior we expect of command line programs.
89
90Let’s run the program again with arguments that don’t cause an error but still
91redirect standard output to a file, like so:
92
93```text
94$ cargo run to poem.txt > output.txt
95```
96
97We won’t see any output to the terminal, and *output.txt* will contain our
98results:
99
100<span class="filename">Filename: output.txt</span>
101
102```text
103Are you nobody, too?
104How dreary to be somebody!
105```
106
107This demonstrates that we’re now using standard output for successful output
108and standard error for error output as appropriate.
109
110## Summary
111
112This chapter recapped some of the major concepts you’ve learned so far and
113covered how to perform common I/O operations in Rust. By using command line
114arguments, files, environment variables, and the `eprintln!` macro for printing
115errors, you’re now prepared to write command line applications. By using the
116concepts in previous chapters, your code will be well organized, store data
117effectively in the appropriate data structures, handle errors nicely, and be
118well tested.
119
120Next, we’ll explore some Rust features that were influenced by functional
121languages: closures and iterators.