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