Learn › Linux Foundations › I/O Redirection

Chapter 11, Part 2. I/O Redirection: the pipe, chains, tee and redirects together

Final test: Chapter 11, I/O Redirection. Twenty-five objectives on a real Debian 12 server covering both parts: the three streams, , , <, 2, 2&1, & and /dev/null, then the pipe, chains of pipes, tee, and pipes combined with redirects. Fifty minutes, sixteen objectives graded on the exact bytes of the files you produce.

Chapter 11, Part 2. I/O Redirection

This chapter covers the following topics:

This part covers Sections 11.10 to 11.13. Part 1 covered Sections 11.1 to 11.9.

You can already connect a command to a file. Now connect one command to another.

Objectives

By the end of this part, you will be able to:

You will use the same ~/io practice area as Part 1. Its healthcheck program produces four OK lines and two ERROR lines; checklist.txt holds eight lines. The predictable input lets you check every result.

Before the practice machine starts, exercise cards show recorded examples. Once it is running, use the real Terminal and inspect the files after each exercise. File changes from Part 1 remain in the same practice session; a newly opened terminal starts a new shell. Append commands add data each time you run them. The chapter assessment covers both parts on a separate machine.

Pre-check 1 of 5: what a pipe carries

Try these short questions to check your starting point. The explanation will help you if you are unsure.

Pre-check 2 of 5: screen and file at once

Pre-check 3 of 5: three commands in a row

Pre-check 4 of 5: what tee does with the lines it saves

Pre-check 5 of 5: where a redirect goes in a pipeline

11.10 The pipe

A pipe, |, connects one command's stdout to the next command's stdin. You can process output without first saving an intermediate file.

Worked command: io/healthcheck | wc -l

The four OK lines flow into wc -l, which counts them. stderr is separate and still reaches the terminal. Try it: expect two error lines and a count of 4.

prompt: admin@server1:~$ answer: io/healthcheck | wc -l ||| io/healthcheck|wc -l ||| ~/io/healthcheck | wc -l output: ERROR log rotation has not run ERROR the mail queue is not draining 4 hint: Section 11.10. The program io/healthcheck (or ~/io/healthcheck from anywhere), the pipe operator |, then the counting tool with its line option -l.

The count is four because plain | carries stdout only. wc counts incoming lines; it does not choose lines by the word OK.

Pipeline commands can run concurrently. Here wc waits for the end of input before printing its total. If you expected six, the next step shows how to include stderr.

11.10 Putting stderr into the pipe

To count results and diagnostics together, put stderr into the same pipe as stdout.

Try io/healthcheck 2>&1 | wc -l. Bash connects stdout to the pipe first, then applies 2>&1 to the command on the left. Expect a single count of 6.

prompt: admin@server1:~$ answer: io/healthcheck 2>&1 | wc -l ||| io/healthcheck |& wc -l ||| ~/io/healthcheck 2>&1 | wc -l output: 6 hint: Section 11.10. The program io/healthcheck (or ~/io/healthcheck from anywhere), the merge operator 2>&1 from Section 11.8, then the pipe | and the counting tool with its line option -l.

All six lines became input to wc, so the errors no longer print separately. Keep 2>&1 on the left of the bar; it changes the left command's stderr.

For this command, Bash's |& form gives the same result. It is not part of portable POSIX shell syntax.

11.10 Cutting the output short

A pipe can feed a reader other than wc. head -n 2 keeps the first two input lines.

Try io/healthcheck 2> /dev/null | head -n 2.

Here 2> /dev/null discards diagnostics from the practice program. Its stdout enters the pipe, and head prints the first two OK lines.

prompt: admin@server1:~$ answer: io/healthcheck 2> /dev/null | head -n 2 ||| io/healthcheck 2>/dev/null | head -n 2 ||| ~/io/healthcheck 2> /dev/null | head -n 2 output: OK web server responds on port 80 OK disk space is above the threshold hint: Section 11.10. The program io/healthcheck (or ~/io/healthcheck from anywhere), stream 2 to /dev/null, then the pipe | and the tool that prints the start of a file with a count of two.

Only two results remain. Discarding stderr made this demonstration easier to read; it did not make those messages part of the pipe.

If errors also appear on the terminal, check the 2> /dev/null part. Without it, they bypass the pipe and remain visible.

11.11 Chains of pipes

A pipeline can have more than two commands. Follow the data one stage at a time.

Try io/healthcheck | tac | head -n 2:

1. healthcheck supplies four result lines on stdout. 2. tac reverses those lines. 3. head -n 2 prints the first two of the reversed set.

Expect the last two OK lines in reverse order. The two errors still go directly to the terminal.

prompt: admin@server1:~$ answer: io/healthcheck | tac | head -n 2 ||| ~/io/healthcheck | tac | head -n 2 output: ERROR log rotation has not run ERROR the mail queue is not draining OK the certificate is valid OK the nightly backup was verified hint: Section 11.11. The program io/healthcheck (or ~/io/healthcheck from anywhere), a pipe into the reversing tool from Chapter 5, another pipe, then the tool that prints the start with a count of two.

The certificate line appears before the backup line because tac reversed the results. head then kept two of them.

tac must read to the end before it knows which line to print first. Different filters behave differently; not every pipeline prints as soon as its first input arrives.

11.12 Screen and file at once: tee

Use tee when you want to see a stream and save a copy in one run. tee reads stdin, writes to its file arguments, and also passes the bytes to stdout.

Try cat io/checklist.txt | tee io/out/pipes/tapped.txt.

Expect the eight checklist lines on the terminal and the same eight lines in the file. By default, tee replaces an existing output file.

prompt: admin@server1:~$ answer: cat io/checklist.txt | tee io/out/pipes/tapped.txt ||| cat ~/io/checklist.txt | tee ~/io/out/pipes/tapped.txt output: check the web server responds check disk space on the root filesystem check the nightly backup ran check the certificate expiry date check the log rotation ran check the mail queue is draining check the firewall rules are loaded check the system clock is in step hint: Section 11.12. The reader from Chapter 5 on io/checklist.txt, a pipe, then the splitting tool and the path io/out/pipes/tapped.txt. Both paths take a ~/ in front to work from anywhere.

The checklist stayed visible because tee copied it to stdout as well as to the file. The next step checks the saved copy.

If you see a file-opening error, do not assume the visible text proves the save worked. Check the destination path and permissions.

11.12 The file tee wrote

Verify the saved copy with cat io/out/pipes/tapped.txt.

Expect the same eight lines that tee displayed.

prompt: admin@server1:~$ answer: cat io/out/pipes/tapped.txt ||| cat ~/io/out/pipes/tapped.txt output: check the web server responds check disk space on the root filesystem check the nightly backup ran check the certificate expiry date check the log rotation ran check the mail queue is draining check the firewall rules are loaded check the system clock is in step hint: Section 11.12. The reader from Chapter 5 and the path io/out/pipes/tapped.txt (or ~/io/out/pipes/tapped.txt from anywhere).

One pipeline produced both a visible stream and a saved record. This is useful when reviewing the output of a longer job.

Remember that plain | fed tee stdout only. If the producing command also has diagnostics, include them deliberately when you want them in the saved record.

11.12 tee truncates too

tee file replaces the file. tee -a file appends, preserving what was already there.

Before trying append mode, inspect the existing journal with head -n 1 io/out/pipes/journal.txt. Expect its opening line.

prompt: admin@server1:~$ answer: head -n 1 io/out/pipes/journal.txt ||| head -n 1 ~/io/out/pipes/journal.txt output: journal opened by the maintenance script hint: Section 11.12. The tool that prints the start of a file, with a count of one and the path io/out/pipes/journal.txt (or ~/io/out/pipes/journal.txt from anywhere).

The journal starts with journal opened by the maintenance script. The next step should keep this line.

If the file was changed during earlier practice, its current contents may differ. Restarting with io/reset resets all result files, not only this journal.

11.12 Appending with tee -a

Append the checklist to the journal while keeping it visible.

Try cat io/checklist.txt | tee -a io/out/pipes/journal.txt once. -a changes what happens to the file; it does not stop tee from writing to stdout.

prompt: admin@server1:~$ answer: cat io/checklist.txt | tee -a io/out/pipes/journal.txt ||| cat ~/io/checklist.txt | tee -a ~/io/out/pipes/journal.txt output: check the web server responds check disk space on the root filesystem check the nightly backup ran check the certificate expiry date check the log rotation ran check the mail queue is draining check the firewall rules are loaded check the system clock is in step hint: Section 11.12. The same pipeline as Exercise 11-38 with the option that appends, -a, and the journal path io/out/pipes/journal.txt (or ~/io/out/pipes/journal.txt from anywhere).

The eight checklist lines appear on the terminal and are added after the journal's existing line.

On the real machine, a second run adds another eight lines. Read the journal next before deciding whether to repeat the append.

11.12 The journal now

Try cat io/out/pipes/journal.txt.

Expect nine lines: the original journal line followed by the eight checklist lines.

prompt: admin@server1:~$ answer: cat io/out/pipes/journal.txt ||| cat ~/io/out/pipes/journal.txt output: journal opened by the maintenance script check the web server responds check disk space on the root filesystem check the nightly backup ran check the certificate expiry date check the log rotation ran check the mail queue is draining check the firewall rules are loaded check the system clock is in step hint: Section 11.12. The reader from Chapter 5 and the path io/out/pipes/journal.txt (or ~/io/out/pipes/journal.txt from anywhere).

Nine lines show that the append kept the original entry. Seventeen would mean the eight-line checklist was appended twice.

If you need to restart, io/reset restores all files under io/out; earlier saved results there will also need to be recreated.

11.13 Pipes and redirects together

A redirect belongs to a specific command in a pipeline. Put it on the command whose output you want to save.

Try io/healthcheck | tac > io/out/pipes/reversed.txt.

The pipe feeds stdout into tac. The > beside tac saves its reversed output. Expect the two original error lines on the terminal because the first command's stderr is still separate.

prompt: admin@server1:~$ answer: io/healthcheck | tac > io/out/pipes/reversed.txt ||| ~/io/healthcheck | tac > ~/io/out/pipes/reversed.txt output: ERROR log rotation has not run ERROR the mail queue is not draining hint: Section 11.13. The program io/healthcheck, a pipe into the reversing tool, then the stream 1 operator > and the path io/out/pipes/reversed.txt. Both paths take a ~/ in front to work from anywhere.

The four results went through tac into the file. The errors bypassed both the pipe and tac's output redirect.

If the file is empty, check which command has > attached to it. Redirecting the producer's stdout away from the pipe leaves the next command with no data.

11.13 The reversed file

Try cat io/out/pipes/reversed.txt.

Expect four OK lines, with the certificate line first and the web-server line last.

prompt: admin@server1:~$ answer: cat io/out/pipes/reversed.txt ||| cat ~/io/out/pipes/reversed.txt output: OK the certificate is valid OK the nightly backup was verified OK disk space is above the threshold OK web server responds on port 80 hint: Section 11.13. The reader from Chapter 5 and the path io/out/pipes/reversed.txt (or ~/io/out/pipes/reversed.txt from anywhere).

The saved text is tac's output, not the original order from healthcheck. No errors are present because they never entered the pipe.

If the order has not changed, check that the previous command actually included tac.

11.13 A chain into a file

Combine reading, selecting and saving in one pipeline.

Try cat io/checklist.txt | head -n 3 > io/out/pipes/top3.txt.

cat supplies eight lines, head -n 3 keeps three, and > saves only those three. Expect no normal output on the terminal.

prompt: admin@server1:~$ answer: cat io/checklist.txt | head -n 3 > io/out/pipes/top3.txt ||| cat ~/io/checklist.txt | head -n 3 > ~/io/out/pipes/top3.txt output: hint: Section 11.13. The reader on io/checklist.txt, a pipe into the tool that prints the start with a count of three, then the stream 1 operator > and the path io/out/pipes/top3.txt. Both paths take a ~/ in front to work from anywhere.

The redirect belongs to head, so its selected lines went to the file. The next step verifies them.

With an existing file, head -n 3 io/checklist.txt > io/out/pipes/top3.txt is a shorter way to get the same result. This exercise practices the pipeline form for when another command supplies the input.

11.13 The trimmed file

Verify the result with cat io/out/pipes/top3.txt.

Expect the checklist's first three lines: the web server, disk space and nightly backup checks.

prompt: admin@server1:~$ answer: cat io/out/pipes/top3.txt ||| cat ~/io/out/pipes/top3.txt output: check the web server responds check disk space on the root filesystem check the nightly backup ran hint: Section 11.13. The reader from Chapter 5 and the path io/out/pipes/top3.txt (or ~/io/out/pipes/top3.txt from anywhere).

Three of the eight input lines were saved. You can now trace a pipeline by asking two questions: what does each command read, and where does it write?

If you see all eight lines, check head -n 3. If the file is empty, check where the output redirect was placed.

Errors you will meet

Visible output does not prove a file was saved. Try to save with cat io/checklist.txt | tee /etc/report.txt as an account without write permission there, and the example result is:

tee: /etc/report.txt: Permission denied
check the web server responds
check disk space on the root filesystem
check the nightly backup ran
check the certificate expiry date
check the log rotation ran
check the mail queue is draining
check the firewall rules are loaded
check the system clock is in step

tee reports the failed file open but still copies input to stdout. Use the requested writable path under ~/io/out and verify the file. The component opening the file reports the error: tee for its file argument, Bash for a shell redirect such as >.

The count is zero, with no error. cat io/checklist.txt > /dev/null | wc -l produces:

0

Bash connects the pipeline first, then applies the command's redirects. Here > moves cat's stdout away from the pipe and into /dev/null. wc reaches the end of an empty input stream.

Check the command that owns the redirect. To save the final result, put > on the final command; to count the checklist through a pipe, leave cat's stdout connected to that pipe.

Summary

Trace one command at a time, then verify any file you created.

Review all key topics

Practice Chapter 11, Part 2. I/O Redirection: the pipe, chains, tee and redirects together in a real Linux terminal at The Linux Camp. Progress is verified automatically as you type commands on the machine.

More lessons in I/O Redirection

Key topicWhat it isSection
The three streams and their operatorsstdin 0, stdout 1, stder