Redirection and streams
Send output to files, read input from them, keep errors apart, and write files with heredocs.
- Name the three standard streams and their numbers
- Redirect output and errors with >, >>, 2>, 2>&1 and &>, and input with <
- Feed text to commands with heredocs, here-strings and tee
Every program starts with three open streams, numbered with file descriptors:
| Number | Name | Normally connected to |
|---|---|---|
| 0 | stdin (standard input) | your keyboard |
| 1 | stdout (standard output) | the terminal |
| 2 | stderr (standard error) | the terminal |
Results go to stdout; complaints and progress messages go to stderr. Both normally land on your screen, so they look the same - but because they’re separate, you can send them to different places. That’s redirection, and the shell sets it up before the command even starts.
| Syntax | Effect |
|---|---|
cmd > file | stdout to file, replacing what was there |
cmd >> file | stdout appended to the end of file |
cmd < file | stdin read from file |
cmd 2> file | stderr to file |
cmd 2> /dev/null | stderr thrown away (/dev/null swallows everything) |
cmd > file 2>&1 | stdout to file, then stderr to wherever stdout now goes |
cmd &> file | Bash shorthand for both streams to file |
echo "oops" >&2 | send your own message to stderr |
1cd "$(mktemp -d)"
2touch manifest.txt
3ls manifest.txt ghost.txt > found.txt 2> errors.txt
4echo "found: $(cat found.txt)"
5echo "errors: $(cat errors.txt)"
6
7echo "first" > log.txt
8echo "second" >> log.txt
9echo "third" > log.txt # > starts over!
10cat log.txt
11wc -l < log.txt # < feeds the file to stdin, so wc prints no namefound: manifest.txt errors: ls: cannot access 'ghost.txt': No such file or directory third 1
Try it
Where does the text go?
Each command produces some normal output and an error message. For the part named in brackets, decide where it ends up.
“ls real fake > out.txt - [the error]”
“ls real fake > out.txt - [the listing]”
“ls real fake 2> /dev/null - [the error]”
“ls real fake &> all.txt - [the error]”
“ls real fake 2>&1 > out.txt - [the error]”
“ls real fake > out.txt 2>&1 - [the error]”
Heredocs, here-strings and tee
A heredoc feeds several lines to a command’s stdin, up to a marker word you choose (EOF by convention). It’s the neatest way to write a file from a script:
<<EOFexpands variables and$(...)inside the text.<<'EOF'(marker quoted) keeps the text exactly as written - use it when the text contains$.<<-EOFalso strips leading tab characters, so you can indent the body.
A here-string, <<< "text", feeds a single string. And tee file copies its stdin to a file and to stdout - like a T-junction in a pipe - so you can save output while still watching it.
1cd "$(mktemp -d)"
2captain="Ada"
3cat > crew.conf <<EOF
4station=Kestrel
5captain=$captain
6EOF
7cat crew.conf
8cat <<'EOF'
9Literal: $captain stays as typed
10EOF
11tr a-z A-Z <<< "hello, $captain"
12echo "saved and shown" | tee copy.txt
13cat copy.txtstation=Kestrel captain=Ada Literal: $captain stays as typed HELLO, ADA saved and shown saved and shown
Key takeaways
stdin is 0, stdout is 1, stderr is 2 - results and errors travel separately.
>replaces,>>appends,<reads,2>captures errors,&>captures both.2>&1copies the current target of stdout, so its position matters.Heredocs write multi-line text (quote the marker to stop expansion);
teesaves and shows at once.
Lesson quiz
7 questions · pass with 5 correct · up to 50 XP
Passing this quiz completes the lesson and keeps your streak going. Questions you miss come back in review sessions later.
Practice: write Bash scripts
Write a script in the editor and run it for real against sample input. Each run gets a fresh Linux sandbox with Bash 5.2 and the GNU tools on Wandbox, a free public service - so experiment freely, even with rm. Your script and test input are sent there.
Separate the signals
The starter defines scan, a command that prints good readings on stdout and faults on stderr. Run scan once, sending stdout to ok.txt and stderr to faults.txt. Then append the line deck5 ok to ok.txt. The provided commands at the end print the files and count the lines in ok.txt.
Expected output:
1ok:
2deck1 ok
3deck3 ok
4deck5 ok
5faults:
6deck2 FAULT
7deck4 FAULT
83- Streams are separated
Your script runs with Bash 5.2 and GNU tools on Wandbox, a free public service, in a fresh sandbox each time. Your script and test input are sent to that service.
Write the config with a heredoc
Use one heredoc to write station.conf with three lines: name=Kestrel, orbit=low and captain= followed by the value of the captain variable. Then print the file with cat, and finally print the captain’s name in capitals using tr a-z A-Z with a here-string.
Expected output:
1name=Kestrel
2orbit=low
3captain=Grace
4GRACE- Writes the config
Your script runs with Bash 5.2 and GNU tools on Wandbox, a free public service, in a fresh sandbox each time. Your script and test input are sent to that service.
Questions about this lesson
Stuck? Ask. Figured something out? Share it. Explaining is one of the best ways to learn.
Loading posts…