Read

Module 3 · Text, redirection and pipes

tee, /dev/null and the standard streams recap

Split output so it goes to a file and the screen at once, throw away what you do not want, and consolidate everything you know about stdin, stdout and stderr.

What you will learn

  • Use tee and tee -a to save output while still seeing it.
  • Use /dev/null to discard output or errors and as an empty input.
  • Combine pipes and redirections of all three streams in one command line.

A pipe sends output to one place and a redirection to another, but sometimes you want both: to watch a long command's progress on the screen *and* keep a copy in a file. That is tee, named after the T-shaped pipe fitting. Its opposite is /dev/null, the place you send output you never want to see. Between them they close the module on streams, so this lesson also pulls everything together in one table.

tee: one input, two outputs

command | tee file writes everything that flows through the pipe into file and also passes it on to stdout, so you still see it and can keep piping: make 2>&1 | tee build.log | grep -i error saves the whole build log while showing only the errors. tee -a appends instead of overwriting. You can give tee several file names to write the same data to all of them.

~% ls /etc | head -3 | tee first3.txt
fstab
group
hostname
~% cat first3.txt
fstab
group
hostname
~% echo 'run 2' | tee -a run.log
run 2
~% cat run.log
run 1
run 2
~% ls /root /nope > ok.txt 2>/dev/null
~% cat ok.txt
/root:
~% cat /dev/null | wc -c
0

/dev/null: the bit bucket

/dev/null is a device file that accepts any amount of data and stores none of it; reading from it returns end-of-file immediately. Three uses come up constantly: 2>/dev/null hides error messages you have decided are noise; >/dev/null hides normal output when you only care about the exit status, as in if grep -q pattern file; and </dev/null gives a command an empty stdin so it cannot wait for the keyboard.

The streams, all in one place

Syntaxstdin (0)stdout (1)stderr (2)
cmdkeyboardscreenscreen
cmd < ffile fscreenscreen
cmd > fkeyboardfile fscreen
cmd 2> fkeyboardscreenfile f
cmd > f 2>&1keyboardfile ffile f
cmd \| otherkeyboardother's stdinscreen
cmd \| tee fkeyboardfile f and screenscreen
cmd 2>/dev/nullkeyboardscreendiscarded

Putting it together

A realistic line uses several of these at once. find / -name '*.conf' 2>/dev/null | sort | tee confs.txt | wc -l searches the whole disk, hides the permission errors, sorts the paths, keeps them in a file and prints how many there were. Read it left to right, one bar at a time, asking what text flows through, and nothing in it is mysterious. That habit, more than any single command, is what this module was about.

One detail specific to this VM: there are no /dev/stdout or /dev/stderr files, which some scripts use as targets. Use >&2 to write to stderr and plain stdout for stdout; both are portable and work everywhere.

Commands in this lesson

CommandWhat it does
cmd | tee fileSave stdout to file and still show it.
cmd | tee -a fileSame, appending to file.
cmd | tee f1 f2Write the output to several files at once.
cmd > /dev/nullDiscard normal output.
cmd 2> /dev/nullDiscard error messages.
cmd > /dev/null 2>&1Discard everything; keep only the exit status.
cmd < /dev/nullRun cmd with an empty stdin.

Quiz

  1. What does `sort data.txt | tee sorted.txt` do?

    • Writes the sorted lines to sorted.txt and also prints them
    • Writes them to sorted.txt silently
    • Prints sorted.txt and data.txt side by side
  2. Which command hides both output and errors, keeping only the exit status?

    • `cmd > /dev/null`
    • `cmd 2> /dev/null`
    • `cmd > /dev/null 2>&1`
  3. What happens when a program reads from /dev/null?

    • It blocks waiting for data
    • It gets end-of-file immediately
    • It reads zeros forever
  4. How do you add a command's output to the end of log.txt while still watching it?

    • `cmd >> log.txt`
    • `cmd | tee -a log.txt`
    • `cmd | tee log.txt`

Practice

  1. Sort /root/lab/l30/data.txt and, in one command, save the sorted lines in /root/lab/l30/sorted.txt while they also appear on the screen.

  2. /root/lab/l30/run.log contains `run 1`. Using echo and tee, append the line `run 2` to it so that the line is also shown on screen.

  3. /root/lab/l30/noisy is a program that prints `ok: 3 files processed` on stdout and `warning: cache is cold` on stderr. Run it so that the normal output is saved in /root/lab/l30/ok.txt and the warning is discarded.

Open this lesson in the app to do the tasks in a real Linux machine and have them checked.