Skip to content

17. Bash Redirections

Overview

Bash provides redirection mechanisms that allow you to control where command input, standard output, and standard error are sent.

Redirection is especially useful when writing scripts, saving command output to files, suppressing errors, logging program execution, and combining normal output with error messages.

Standard Streams

Linux commands normally work with three standard streams:

File Descriptor Name Purpose
0 STDIN Standard input
1 STDOUT Standard output
2 STDERR Standard error

By default:

STDIN  → Keyboard
STDOUT → Terminal
STDERR → Terminal

The file descriptors can be explicitly referenced during redirection.

STDOUT to Screen

Standard output is displayed on the terminal by default.

Create a file:

touch file1

Then run:

ls file1

Output:

file1

The output from ls is STDOUT, and because no redirection is specified, it is displayed on the screen.

This is equivalent to:

ls file1 1>&1

although explicitly redirecting STDOUT to itself is unnecessary.

STDOUT to a File

The > operator redirects STDOUT to a file.

ls file1 > STDOUT.txt

Now the output is written to STDOUT.txt instead of being displayed on the terminal.

Read the file:

cat STDOUT.txt

Output:

file1

The general syntax is:

command > file

This is equivalent to:

command 1> file

Important: > Overwrites the File

If the file already exists, > replaces its contents.

echo "First line" > output.txt
echo "Second line" > output.txt

The file contains only:

Second line

To append instead of overwrite, use >>:

echo "First line" > output.txt
echo "Second line" >> output.txt

Output:

First line
Second line

STDERR to Screen

Standard error is also displayed on the terminal by default.

For example:

ls file2

If file2 does not exist:

ls: cannot access 'file2': No such file or directory

This message is sent through STDERR, not STDOUT.

STDERR to a File

Use 2> to redirect STDERR to a file.

ls file1 file2 2> STDERR.txt

If file1 exists and file2 does not, STDOUT remains on the screen:

file1

The error is written to STDERR.txt.

Check the file:

cat STDERR.txt

Output:

ls: cannot access 'file2': No such file or directory

The general syntax is:

command 2> error.log

This is useful when you want to separate normal output from error messages.

STDOUT to STDERR

STDOUT can be redirected to the same destination as STDERR using:

1>&2

Example:

#!/bin/bash

echo "Redirect this STDOUT to STDERR" 1>&2

Normally, echo writes to STDOUT.

The following changes its destination so that STDOUT uses the same file descriptor as STDERR.

Run the script normally:

./redirecting.sh

Output:

Redirect this STDOUT to STDERR

Now redirect STDOUT:

./redirecting.sh > STDOUT.txt

Check the file:

cat STDOUT.txt

There is no output because the message was sent through STDERR.

Now redirect STDERR:

./redirecting.sh 2> STDERR.txt

Check the file:

cat STDERR.txt

Output:

Redirect this STDOUT to STDERR

This demonstrates that the echo output was redirected from STDOUT to STDERR.

STDERR to STDOUT

The reverse operation is:

2>&1

This redirects STDERR to the same destination currently used by STDOUT.

Example:

cat /etc/shadow 2>&1

If access is denied, the error message is redirected to STDOUT.

Output:

cat: /etc/shadow: Permission denied

Now redirect STDOUT to a file:

cat /etc/shadow 2>&1 > STDOUT.txt

There is an important ordering detail here: redirections are processed from left to right.

A safer common pattern for sending both streams to one file is:

cat /etc/shadow > STDOUT.txt 2>&1

Here:

STDOUT → STDOUT.txt
STDERR → same destination as STDOUT

Therefore both streams go to the file.

Redirecting Both STDOUT and STDERR to the Same File

A common requirement is to save both normal output and errors in one log file.

Use:

ls file1 file2 > output.log 2>&1

This performs two operations:

1. STDOUT → output.log
2. STDERR → same destination as STDOUT

Check the file:

cat output.log

Example:

ls: cannot access 'file2': No such file or directory
file1

Both STDOUT and STDERR are stored in the same file.

Using &> for Both Streams

Bash provides a shorter syntax:

command &> output.log

For example:

ls file1 file2 &> output.log

Then:

cat output.log

Output:

ls: cannot access 'file2': No such file or directory
file1

The &> syntax redirects both:

STDOUT + STDERR → file

This is convenient when writing Bash scripts.

Appending Both STDOUT and STDERR

To append both streams instead of overwriting the file:

command &>> output.log

Example:

echo "Starting scan" &>> output.log
ls file1 file2 &>> output.log

The existing contents of output.log are preserved and new output is appended.

The equivalent traditional form is:

command >> output.log 2>&1

Suppressing Output

The special file /dev/null can be used to discard output.

Suppress STDOUT:

command > /dev/null

Suppress STDERR:

command 2> /dev/null

Suppress both:

command > /dev/null 2>&1

Or, in Bash:

command &> /dev/null

For example:

ls file1 file2 &> /dev/null

Nothing is displayed on the terminal.

This is commonly useful when you only care about whether a command succeeds or fails.

Redirection Order Matters

Redirections are processed from left to right.

Consider:

command > output.log 2>&1

The shell first performs:

STDOUT → output.log

Then:

STDERR → same destination as STDOUT

So both go to the file.

Compare this with:

command 2>&1 > output.log

The shell first performs:

STDERR → current STDOUT

At that point STDOUT is still the terminal.

Then:

STDOUT → output.log

Therefore STDOUT goes to the file, while STDERR can still go to the terminal.

This difference is important when combining redirections.

Common Redirection Operators

Syntax Meaning
> Redirect STDOUT and overwrite file
>> Redirect STDOUT and append to file
2> Redirect STDERR and overwrite file
2>> Redirect STDERR and append to file
1> Explicitly redirect STDOUT
1>> Explicitly append STDOUT
2>&1 Redirect STDERR to STDOUT's current destination
1>&2 Redirect STDOUT to STDERR's current destination
&> Redirect STDOUT and STDERR to a file
&>> Append STDOUT and STDERR to a file
/dev/null Discard output

Practical Logging Example

Redirection is frequently used to create simple Bash logs.

#!/bin/bash

LOGFILE="script.log"

echo "Script started" >> "$LOGFILE"

echo "Checking files..." >> "$LOGFILE"

ls /etc/passwd /does-not-exist >> "$LOGFILE" 2>&1

echo "Script finished" >> "$LOGFILE"

The log file can contain:

Script started
Checking files...
/etc/passwd
ls: cannot access '/does-not-exist': No such file or directory
Script finished

Both successful command output and error messages are recorded in the same log.

Practical Example: Separate Output and Errors

You can keep normal output and errors in separate files:

#!/bin/bash

ls /etc /does-not-exist > output.log 2> error.log

View normal output:

cat output.log

View errors:

cat error.log

This separation can be useful when troubleshooting scripts or analyzing command execution.

Key Takeaways

  • STDIN uses file descriptor 0.

  • STDOUT uses file descriptor 1.

  • STDERR uses file descriptor 2.

  • > redirects STDOUT and overwrites the destination file.

  • >> redirects STDOUT and appends to the file.

  • 2> redirects STDERR.

  • 2>&1 redirects STDERR to the current STDOUT destination.

  • 1>&2 redirects STDOUT to the current STDERR destination.

  • &> redirects both STDOUT and STDERR.

  • /dev/null can be used to discard output.

  • Redirection order matters because Bash processes redirections from left to right.

  • > output.log 2>&1 is a common pattern for saving both STDOUT and STDERR to the same file.