LearnLinux FoundationsI/O Redirection

Catch Errors with 2>

2> - a hands-on Linux lab on a real virtual machine.

Steer the error channel. Prove errors ride channel 2 by watching one line refuse to leave the screen, then catch complaints in a file with 2, capture a real ls error, and read the evidence back, all in the practice terminal.

You have a folder called signal in your home directory. Inside it are a few small text files and one little script called report.sh. Run it and it says three things: the system is nominal, all checks passed, and one sensor is offline. Two lines of good news, one complaint.

Remember from the > lesson: the > operator takes what a command prints and sends it into a file or another destination instead of the screen. Time to put that to the test. You are going to point the report's output at /dev/null, a special file that swallows anything written to it. It gets a full lesson later in this module; for now all you need is this: output sent there disappears.

Before you run this, decide: if everything a command prints travels together as one stream, then throwing the output away should leave the screen completely blank. Commit to a prediction, then run it.

prompt: student@linuxcamp:~/signal$ answer: bash report.sh >/dev/null output: report: sensor offline hint: Run the script with bash, then point > at the discard file: bash report.sh >/dev/null

One line survived. You told > to dump everything report.sh prints, and yet the complaint about the sensor still landed on your screen. > did not miss; it did its job perfectly. The trick is that this line was never part of the normal output at all. It travels on a separate channel that > cannot touch, and by the end of this lesson you will steer that channel anywhere you want with one small operator: 2>.

The black boxes here are a practice terminal: a safe sandbox that only checks the one command each step teaches, so you cannot break anything. On the real machine at the end of the module, the mission builds this same signal folder, and you run these redirects for real.

Remember from the file descriptors lesson: every Linux command is born wired to three numbered channels.

The two good-news lines from report.sh travel on channel 1, stdout. The sensor complaint travels on channel 2, stderr. On a plain terminal both channels end at the same screen, which is why the three lines look identical when they arrive. They were never the same; they just share a destination.

Here is the secret about the operator you already know: plain > is really 1>. Write nothing in front of the arrow and the shell assumes channel 1. That is why the complaint escaped in the last step. To grab the error channel instead, name it: put a 2 directly in front of the arrow. command 2> file sends only stderr into the file, while stdout keeps flowing to the screen. That one character is the whole lesson.

stderr exists because of a printer. In early Unix at Bell Labs, output was often sent straight to a phototypesetter. When a command failed, its error message got typeset into the middle of the document instead of reaching the person who ran it. A second output channel was added so complaints could always find the terminal, and that channel is the stderr you are about to steer.

Type 2> as one unit, with no space between the 2 and the >. Write 2 > with a gap and the shell treats the 2 as an ordinary argument and redirects the normal output instead.

Time to fix the leak from the cold open. Run the report and steer channel 2 into a file called errors.txt. Here is the flow you are about to create:

{ "caption": "bash report.sh 2> errors.txt: stdout (1) still flows to the screen; 2> re-points stderr (2) into the file.", "nodes": [ { "id": "cmd", "label": "report.sh", "kind": "command", "col": 0, "row": 1 }, { "id": "scr", "label": "your screen", "kind": "screen", "col": 4, "row": 0 }, { "id": "err", "label": "errors.txt", "kind": "file", "col": 4, "row": 2 } ], "edges": [ { "from": "cmd", "to": "scr", "label": "stdout (1)", "kind": "stdout", "stage": 1 }, { "from": "cmd", "to": "err", "label": "2> stderr (2)", "kind": "stderr", "stage": 2 } ] }

Before you run it, decide which of the report's three lines will print. If 2> takes only the error channel, the two good-news lines should still reach the screen and the complaint should vanish into the file.

bash report.sh 2> errors.txt

prompt: student@linuxcamp:~/signal$ answer: bash report.sh 2> errors.txt output: report: system nominal report: all checks passed hint: Put the channel number 2 right against the arrow: bash report.sh 2> errors.txt

The two stdout lines printed exactly as if nothing was redirected, and the complaint is gone from the screen. 2> peeled channel 2 away mid-flight and pointed it at errors.txt, while channel 1 flowed on untouched. This is the mail-sorting trick: routine results on your desk, complaints filed in a folder. But do not take the shell's word for it. If the redirect really worked, that missing line is sitting in the file right now.

Read errors.txt back with cat, the file-printing command you have used since the reading lessons. Before you run it, decide what you expect to find inside: all three report lines, or just one?

cat errors.txt

prompt: student@linuxcamp:~/signal$ answer: cat errors.txt output: report: sensor offline hint: cat, a space, then the file that caught the errors: cat errors.txt

One line, and it is exactly the one that was missing from the screen. Not the good news, only the complaint, because only channel 2 was pointed at the file. That is the surgical part of 2>: it sorts lines by the channel they were born on, not by what they say. Two more facts about that file. First, 2> behaves like >: run the command again and errors.txt is wiped and rewritten. Second, remember from the >> lesson that doubling the arrow appends; the same works here, so 2>> errors.txt adds new complaints under the old ones instead of replacing them.

report.sh is a script we built, but 2> is no report.sh trick. Every well-behaved Linux tool sends results to channel 1 and complaints to channel 2. Take ls, which you have used since your first session. Ask it to list two files where one exists and one does not, and it answers on BOTH channels at once: the found name on stdout, the error on stderr.

Steer its channel 2 into ls-err.txt. Before you run it, decide what the screen will show: the found name, the complaint, or both?

ls fruits.txt nowhere.txt 2> ls-err.txt

prompt: student@linuxcamp:~/signal$ answer: ls fruits.txt nowhere.txt 2> ls-err.txt output: fruits.txt hint: Same 2> shape, on ls this time: ls fruits.txt nowhere.txt 2> ls-err.txt

Only fruits.txt, the name that exists. ls still complained about nowhere.txt, but the complaint rode channel 2 straight into the file. Nobody taught ls about your redirect; the shell rerouted the channel before ls even started. That is why 2> works on every command you will ever run, from scripts you wrote to tools installed with the system.

One more read-back to close the loop. Decide first what the captured line will say, then open the file.

cat ls-err.txt

prompt: student@linuxcamp:~/signal$ answer: cat ls-err.txt output: ls: cannot access 'nowhere.txt': No such file or directory hint: Read the capture file with cat: cat ls-err.txt

Look at the anatomy of that line. It has three parts: the tool's name (ls:), the thing it tried to do (cannot access 'nowhere.txt'), and the reason (No such file or directory). That is the standard shape of a Linux error message, and you just caught one in a jar. You have now split a live command's streams twice, once on a script and once on a core tool. The operator is yours. Time to prove it with the scaffolding removed.

No command is shown from here on.

It is monitoring time in the signal folder. Run the evening report so the healthy lines print to your screen and the complaint is filed into errors.txt where you can review it later.

prompt: student@linuxcamp:~/signal$ answer: bash report.sh 2> errors.txt output: report: system nominal report: all checks passed hint: The channel number rides right in front of the arrow, after the command and before the filename.

Clean screen discipline: the report ran, the good news scrolled by, and the complaint went straight into its file without cluttering your view. That is exactly how engineers keep a script's routine output readable while nothing gets lost.

A teammate asks whether fruits.txt and nowhere.txt both exist. Check both names with a single ls, and keep your screen clean by filing any complaint into ls-err.txt.

prompt: student@linuxcamp:~/signal$ answer: ls fruits.txt nowhere.txt 2> ls-err.txt output: fruits.txt hint: Give ls both names, then steer channel 2 into ls-err.txt.

The screen answered half the question: fruits.txt exists. The other half of the answer is waiting inside the file you filed the complaint into, which is your last challenge.

Prove the second file is missing. Print the complaint that ls just filed, straight from the file it landed in.

prompt: student@linuxcamp:~/signal$ answer: cat ls-err.txt output: ls: cannot access 'nowhere.txt': No such file or directory hint: The reading command you have used all lesson, pointed at the capture file.

There is the proof, in ls's own words: nowhere.txt does not exist. Three challenges, zero prompting. You steered channel 2 from memory, which is the moment an operator stops being trivia and becomes a tool.

You earned this cheat sheet. Every row is something you just ran in the signal folder:

The one idea under all of it: error messages are not special text, they are ordinary text on a separate numbered channel. Plain > means 1> and grabs the normal output; 2> grabs the complaints. Name the channel, point the arrow, and the stream goes where you say.

Two habits to keep. Type 2> as one unit, because 2 > with a gap makes the shell treat the 2 as an argument and redirect stdout instead. And remember that 2> overwrites its file on every run, so reach for 2>> when yesterday's errors still matter.

You can now steer both output channels on their own: > and >> for stdout, 2> and 2>> for stderr. The rest of the module builds directly on this move. &> grabs both channels at once, 2>&1 folds the errors into the normal output, and /dev/null gives you a place to throw either stream away. Each one has its own lesson coming up.

The I/O Redirection module ends with one real Linux machine: the redirection mission lab. There a VM boots just for you with this same signal folder and report.sh already in place, and the mission hands you objectives with no commands shown. You read the objective, recall the operator, and type it. That recall is what makes it stick.

Finish the other I/O Redirection lessons, then go run the mission for real.

Practice Catch Errors with 2> in a real Linux terminal at The Linux Camp. Progress is verified automatically as you type commands on the machine.