Computing and the Command Line

Standard Input, Output, and Error

Every program has three streams: standard input (0), standard output (1), and standard error (2). Send output to files with > and >>, errors with 2>, both with 2>&1 or &>, and unwanted output to /dev/null; feed files in with <, and whole blocks of text with here documents. Why > empties a file before the command runs, and why the order of 2>&1 matters.

  • 6 min
  • 9 steps
  • 3 questions
  • Lesson 10 of 80

In this lesson

  1. Two kinds of output
  2. Output to a file
  3. Errors to a file
  4. Throwing output away
  5. Input from a file
  6. Here documents
  7. Grouping commands
  8. Your turn
  9. So

Two kinds of output

A program usually produces two kinds of output: its results, and messages about how it’s getting on, especially errors. They go to two different places 1:

  • Standard output (stdout) for results.
  • Standard error (stderr) for errors and status messages.

Programs also read from standard input (stdin). By default, input comes from the keyboard and both outputs go to your screen, which is why they look like one stream 1 2.

Internally the shell numbers them as file descriptors: 0 for input, 1 for output, 2 for error 1. Redirection changes where each one points.

A program in the middle. Standard input, 0, comes in from the left, from the keyboard by default, or from a file with < file, or from another program through a pipe. Standard output, 1, goes out to the right, to the screen by default, or to a file with > file to overwrite or >> file to append, or into the next program through a pipe. Standard error, 2, goes down, also to the screen, so errors still show. A terminal lists ways to handle errors: 2> errors.txt sends errors to a file; > all.txt 2>&1 sends both to one file; &> all.txt is bash's shorthand for both; 2> /dev/null throws errors away. A warning: > empties the file before the program even starts.
Results and complaints travel on separate streams. Credit: StudyCorner diagram · CC BY 4.0 · Source

Quick check

You run ls /nope > out.txt. The error shows on screen and out.txt is empty. Why?

Output to a file

> sends standard output to a file instead of the screen 1 2:

me@linuxbox:~$ ls -l /usr/bin > programs.txt
me@linuxbox:~$ less programs.txt

Two things to know about >:

  1. It empties the file first, before the command even runs. If the command produces nothing, or fails, you’re left with an empty file 1. > file on its own, with no command, is a quick way to empty a file or create a blank one.
  2. It overwrites silently. A reader of Shotts’ book, working as root in /usr/bin, typed ls > less to “see what happens”: it replaced the less program with a text listing 1. > points at a file; |, next lesson, points at a program.

>> appends instead, creating the file if it doesn’t exist 1:

me@linuxbox:~$ date >> worklog.txt
me@linuxbox:~$ echo "replaced the furnace filter" >> worklog.txt

Bash can refuse to overwrite with > if you turn on set -o noclobber; then >| forces it 3. Some people put that in their startup file.

Quick check

What happened when an administrator typed ls > less in /usr/bin?

Errors to a file

Redirect standard error with its number, 2> 1:

me@linuxbox:~$ ls -l /bin/usr 2> errors.txt

To catch both streams in one file, there are two ways 1:

me@linuxbox:~$ ls -l /bin/usr > all.txt 2>&1     # the classic way
me@linuxbox:~$ ls -l /bin/usr &> all.txt         # bash's shorthand
me@linuxbox:~$ ls -l /bin/usr &>> all.txt        # shorthand, appending

2>&1 means “send stream 2 wherever stream 1 is going right now.” Redirections are applied left to right, so the order matters: > all.txt 2>&1 points output at the file, then errors at the same place. Written the other way, 2>&1 > all.txt, errors are pointed at the screen (where output was at that moment), and only then does output move to the file 1 3.

Quick check

Which sends BOTH output and errors to log.txt?

Throwing output away

/dev/null is a special file that swallows anything written to it 1. Use it to silence what you don’t want:

me@linuxbox:~$ find / -name "*.conf" 2> /dev/null    # hide the "Permission denied" noise
me@linuxbox:~$ some-noisy-command > /dev/null         # keep only the errors
me@linuxbox:~$ some-command &> /dev/null              # silence everything

The first is something you’ll type constantly: searching the whole system as an ordinary user produces a wall of permission errors, and 2> /dev/null leaves just the results.

Input from a file

< feeds a file to a program’s standard input 1 2:

me@linuxbox:~$ wc -l < /etc/passwd
34

Many programs take a file name anyway, so < matters most for programs that only read standard input. Notice the difference, though: wc -l /etc/passwd prints the name too; wc -l < /etc/passwd prints just the number, because wc never saw a file name.

cat with no arguments copies standard input to standard output, so cat > note.txt, then typing a few lines and pressing Ctrl-D, makes a quick file. Ctrl-D means “end of input” 1.

Here documents

A here document feeds several lines of text, written right in the command, to standard input. Everything up to a line holding only the end marker is the input 1 3:

me@linuxbox:~$ cat > grocery.txt << EOF
oats
apples
coffee
EOF

You’ll use these in scripts to write out config files and messages. A here string, <<<, feeds a single line: wc -w <<< "how many words here" 3.

Grouping commands

To send the output of several commands to one place, group them in braces. The spaces and the final semicolon are required 1:

me@linuxbox:~$ { date; uptime; df -h /; } > status.txt

Your turn

Exercises

  1. Save a long listing of /etc to etc.txt, then append a long listing of /usr/share to the same file. How many lines does it have?
  2. Run ls /etc /nonexistent > out.txt. What appears on screen, and what’s in the file? Now catch both in both.txt.
  3. Search the whole system for files named hosts, showing only results, no errors.
  4. Use a here document to create todo.txt with three lines, then count its lines with wc -l < todo.txt.
  5. Turn on noclobber, try echo hi > todo.txt, read the error, then turn it off with set +o noclobber.
Answers
  1. ls -l /etc > etc.txt, then ls -l /usr/share >> etc.txt, then wc -l etc.txt.
  2. The error for /nonexistent appears on screen; the listing of /etc is in the file. ls /etc /nonexistent &> both.txt (or > both.txt 2>&1) catches both.
  3. find / -name hosts 2> /dev/null. Expect /etc/hosts and a few others.
  4. cat > todo.txt << EOF, three lines, EOF; then wc -l < todo.txt prints 3.
  5. With noclobber on: bash: todo.txt: cannot overwrite existing file. echo hi >| todo.txt would force it.

So

Programs read standard input and write two streams, output and errors. > and >> send output to a file (and > empties it first), 2> sends errors, > file 2>&1 or &> sends both, /dev/null discards, and < and here documents supply input. The shell does all of this before the program runs.

Lesson complete

Nice work.

1day streak
0/1today's goal
–correct

Up next · 5 min

Pipelines and Filters

Next lesson
Sources for this lesson
  1. 1
    William Shotts. The Linux Command Line, Seventh Internet Edition (25.12A). LinuxCommand.org (print edition by No Starch Press). 2026. verifiedFree CC BY-NC-ND 3.0 book, release 25.12A of July 18, 2026. Part 1, Learning the Shell: the shell and terminal emulators, prompts ($ vs. # for the superuser), command history (most distributions keep the last 1,000 commands), Shift-Ctrl-C/V for copy and paste; navigation and the directory tree; exploring the system (ls options and the long listing, file, less, the guided tour of /, symbolic links); manipulating files (wildcards and character classes, mkdir, cp, mv, rm, ln; no undelete, test wildcards with ls first); working with commands (four kinds of commands, type, which, help, --help, man and its sections, apropos, whatis, info, alias); redirection; expansion and quoting; Readline keyboard tricks, completion, history search; permissions; processes. Later parts cover the environment, vi, packages, storage, networking, find, archiving, regular expressions, text processing, and shell scripting.
  2. 2
    Anish Athalye, Jon Gjengset, Jose Javier Gonzalez Ortiz. Course Overview + The Shell (The Missing Semester of Your CS Education, 2020). MIT CSAIL. 2020. verifiedCC BY-NC-SA. Explains ls -l permission bits (directory x is 'search' permission), streams and redirection (<, >, >>, |), root and sudo, and why sudo echo 3 > brightness fails: operations like |, >, and < are done by the shell, not the program, and the shell runs as you, so the shell's attempt to open the file is denied; echo 3 | sudo tee brightness works because tee, running as root, opens the file. Exercises: write a script with a shebang, chmod it executable, and run it.
  3. 3
    Chet Ramey, Brian Fox. Bash Reference Manual, Edition 5.3. GNU Project, Free Software Foundation. 2025. verifiedThe reference for Bash 5.3 (May 18, 2025). Redirections (3.6) are processed left to right and order matters: ls > dirlist 2>&1 sends both streams to dirlist, while ls 2>&1 > dirlist sends only standard output there. With set -o noclobber, > fails on an existing regular file and >| overrides it. &> word is equivalent to > word 2>&1 and &>> word to >> word 2>&1. Here documents (<<word, with <<- stripping leading tabs; quoting word disables expansion) and here strings (<<<). Expansions (3.5) happen in a fixed order: brace; tilde, parameter, arithmetic, and command substitution left to right; word splitting; filename expansion; quote removal last. Startup files (6.2): an interactive login shell reads /etc/profile then the first of ~/.bash_profile, ~/.bash_login, ~/.profile; an interactive non-login shell reads ~/.bashrc. HISTCONTROL (ignorespace, ignoredups, ignoreboth), HISTSIZE, HISTFILESIZE; set -x traces expanded commands; shell functions and variables, export.