Bash
stderr
stdout
scripting
command redirection

Redirect stderr and stdout in Bash

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In Bash, stdout and stderr are separate output streams. stdout is file descriptor 1, stderr is file descriptor 2, and understanding how to redirect them cleanly is essential for logging, scripting, and debugging.

The basic syntax is simple, but the order of redirection matters. Many Bash bugs come from writing the right operators in the wrong sequence.

The Three Standard Streams

Unix-style shells expose three standard file descriptors by default:

  • '0 for standard input'
  • '1 for standard output'
  • '2 for standard error'

A command that prints normal results writes to stdout. Errors and diagnostics usually go to stderr.

bash
echo "normal output"
ls /does-not-exist

The first line goes to stdout. The ls failure message goes to stderr.

Redirect stdout and stderr Separately

Redirect normal output to a file:

bash
command > out.log

Redirect only errors:

bash
command 2> err.log

Redirect both, but to different files:

bash
command > out.log 2> err.log

This is often the cleanest setup in scripts because it preserves a separate error channel.

Redirect Both to the Same Place

A common pattern is sending both streams to one file.

bash
command > all.log 2>&1

This means:

  1. send stdout to all.log
  2. send stderr to wherever stdout is now going

Bash also supports a shorter form:

bash
command &> all.log

That shorthand is Bash-specific and not as portable to other shells, so > file 2>&1 is still the safer habit in portable shell scripts.

Why Order Matters

These two commands are not equivalent:

bash
command > all.log 2>&1
command 2>&1 > all.log

The first sends both streams to the file.

The second first points stderr at the current stdout, which is still the terminal, and only then redirects stdout to the file. The result is:

  • 'stdout goes to the file'
  • 'stderr still goes to the terminal'

This is one of the most important Bash redirection rules to remember.

Append Instead of Overwrite

Use >> when you want to append.

bash
command >> out.log
command 2>> err.log
command >> all.log 2>&1

This is useful for long-running scripts, cron jobs, and repeated local debugging where you want to keep a history of runs.

Silence Output Completely

If you want to discard output, redirect to /dev/null.

bash
command > /dev/null
command 2> /dev/null
command > /dev/null 2>&1

That last version suppresses everything. It is common in scripts, but use it carefully. Silencing stderr can make failures much harder to diagnose.

See Output and Save It with tee

If you want output on screen and in a file, use tee.

bash
command 2>&1 | tee all.log

That combines both streams first and then passes them through tee, which writes to the terminal and the file.

If you only want stdout through tee, redirect stderr separately instead.

Common Pitfalls

The biggest mistake is mixing up the order of redirections. > file 2>&1 and 2>&1 > file do different things.

Another common problem is assuming &> is portable shell syntax. It works in Bash, but not in every shell environment.

People also redirect everything to /dev/null too early in debugging and then wonder why a script fails with no clues.

Finally, remember that tee only sees what reaches it through the pipeline. If you want errors included, merge stderr into stdout before piping.

Summary

  • 'stdout is file descriptor 1, and stderr is file descriptor 2.'
  • Use > file for stdout and 2> file for stderr.
  • Use > file 2>&1 to send both streams to one destination.
  • Redirection order matters.
  • Use >> to append instead of overwrite.
  • Use /dev/null and tee deliberately, not automatically.

Course illustration
Course illustration

All Rights Reserved.