Advanced Bash Scripting

Streams

devnull

Redirecting standard error (stderr) into standard output (stdout) is a powerful shell idiom that helps you capture or suppress all command output in one place. In this guide, we’ll start with basic redirection operators and build up to the full pattern:

2>&1

By the end, you’ll know how to merge streams, write them to files, and even discard them using /dev/null.

1. Basic redirection with >

A single greater‐than symbol sends a file descriptor to a file (or another stream):

$ ls > stdout.txt
  • Left of > is the source FD (default is 1, i.e. stdout).
  • Right of > is the destination (often a filename).

You can explicitly specify the FD:

$ ls 1>stdout.txt    # same as `ls > stdout.txt`
$ ls 2>stderr.txt    # redirect stderr (fd 2) into stderr.txt

Note

When you omit the FD before >, Bash assumes 1 (standard output).

2. Merging stdout and stderr with &>

Bash provides a shorthand to capture both streams at once:

$ ls -z &> all-logs.txt
$ cat all-logs.txt
ls: cannot access '-z': No such file or directory

Here, &> is equivalent to >file 2>&1 in Bash.

3. Duplicating file descriptors using >&n

When & appears on the right side of >, you’re duplicating an FD instead of writing to a filename:

$ echo "warning" >&2    # send stdout (fd 1) into stderr (fd 2)

This is different from &> file.txt, which writes both stdout and stderr into a file.

4. Swapping streams with n>&m

You can redirect one FD into another:

  • Send stdout into stderr:

    $ echo "warning" >&2
    
  • Send stderr into stdout:

    $ ls -z 2>&1
    ls: cannot access '-z': No such file or directory
    

Warning

Order matters when combining redirections. Always redirect stdout first, then redirect stderr into it.

5. Redirecting both streams to a file

To capture both stdout and stderr in a single file, use:

$ ls -z > file.txt 2>&1
  1. > file.txt sends stdout (fd 1) into file.txt.
  2. 2>&1 redirects stderr (fd 2) into wherever stdout is now pointing.

6. Discarding all output with /dev/null

If you want a command to produce no output, redirect both streams to /dev/null, the special “black hole” in Unix-like systems:

> /dev/null 2>&1

The image explains that "/dev/null" is a special file that discards all data written to it.

Use this pattern when you need a silent command—no stdout, no stderr.

The image features the term "/dev/null" with a visual representation of a black hole and checkmarks next to the phrases "Data that is not needed" and "Data should not be saved."


Key takeaways

OperatorPurposeExample
>fileRedirect stdout (fd 1) to a filels > out.txt
2>fileRedirect stderr (fd 2) to a filels -z 2>err.txt
&>fileRedirect both stdout and stderr to a filecmd &>all.txt
n>&mDuplicate FD n into FD mecho "err" >&2
2>&1Merge stderr into stdoutcmd >out.txt 2>&1
> /dev/null 2>&1Discard both stdout and stderrsome_command > /dev/null 2>&1

The image is a slide titled "/dev/null" with checkmarks next to "Redirection," "File descriptors," and "Scenarios where to discard the output."


Watch Video

Watch video content

Previous
File descriptors
Next
Input