Which symbol should I use to redirect the error output to the standard output?

As we can see,

$ cat
hello there
hello there
say it again
say it again
[ctrl+d]
9 is a command that means “output hello”. But where does that output really go?

Standard output

Every Unix-based operating system has a concept of “a default place for output to go”. Since that phrase is a mouthful, everyone calls it “standard output”, or “stdout”, pronounced standard out. Your shell (probably bash or zsh) is constantly watching that default output place. When your shell sees new output there, it prints it out on the screen so that you, the human, can see it. Otherwise

$ cat
hello there
hello there
say it again
say it again
[ctrl+d]
9 would send “hello” to that default place and it would stay there forever.

Standard input

Standard input (“stdin”, pronounced standard in) is the default place where commands listen for information. For example, if you type

$ echo "hello there"
hello there
$ echo "hello there" | sed "s/hello/hi/"
hi there
1 with no arguments, it listens for input on stdin, outputting what you type to stdout, until you send it an EOF character (CTRL+d):

$ cat
hello there
hello there
say it again
say it again
[ctrl+d]

As you can see, with standard input, you can send a string to a command directly.

Pipes

Pipes connect the standard output of one command to the standard input of another. You do this by separating the two commands with the pipe symbol (

$ echo "hello there"
hello there
$ echo "hello there" | sed "s/hello/hi/"
hi there
2). Here’s an example:

$ echo "hello there"
hello there
$ echo "hello there" | sed "s/hello/hi/"
hi there

$ echo "hello there"
hello there
$ echo "hello there" | sed "s/hello/hi/"
hi there
3 prints
$ echo "hello there"
hello there
$ echo "hello there" | sed "s/hello/hi/"
hi there
4 to stdout. But when we pipe it to
$ echo "hello there"
hello there
$ echo "hello there" | sed "s/hello/hi/"
hi there
5, sed takes that output as its input and replaces “hello” with “hi”, then prints out that result to stdout. Your shell only sees the final result after it’s been processed by sed, and prints that result to the screen.

Hey, if sed sends its result to standard out, can we pipe sed to another sed? Yep!

$ echo "hello there" | sed "s/hello/hi/" | sed "s/there/robots/"
hi robots

Above, we’ve connected echo to sed, then connected that to another sed. Pipes are great for taking output of one command and transforming it using other commands like jq. They’re a key part of the Unix philosophy of “small sharp tools”: since commands can be chained together with pipes, each command only needs to do one thing and then hand it off to another command.

Standard error

Standard error (“stderr”) is like standard output and standard input, but it’s the place where error messages go. To see some stderr output, try catting a file that doesn’t exist:

$ cat does-not-exist
cat: does-not-exist: No such file or directory

Hey, that output looks just like stdout! But wait a moment. Let’s try transforming that output with pipes:

$ cat does-not-exist | sed 's/No such/ROBOT SMASH/'
cat: does-not-exist: No such file or directory

Whoa - nothing changed! Remember, pipes take the stdout of the command to the left of the pipe.

$ echo "hello there"
hello there
$ echo "hello there" | sed "s/hello/hi/"
hi there
1‘s error output went to stderr, not stdout, so nothing came through the pipe to sed. It’s good that stderr doesn’t go through the pipe by default: when we pipe output through something that doesn’t output stdout to the terminal, we still want to see errors immediately. For example, imagine a command that reads stdin and sends it to the printer: you wouldn’t want to have to walk over to the printer to see its errors.

We need to redirect

$ echo "hello there"
hello there
$ echo "hello there" | sed "s/hello/hi/"
hi there
1’s stderr to stdout so that it goes through the pipe. And that means we need to learn about redirecting output.

Redirecting output

By default, stdout and stderr are printed to your terminal – that’s why you can see them at all. But we can redirect that output to a file using the

$ echo "hello there"
hello there
$ echo "hello there" | sed "s/hello/hi/"
hi there
8 operator:

$ echo hello
hello
$ echo hello > new-file
$ cat new-file
hello

The second

$ echo "hello there"
hello there
$ echo "hello there" | sed "s/hello/hi/"
hi there
9 didn’t print anything to the terminal because we redirected its output to a file named
$ echo "hello there" | sed "s/hello/hi/" | sed "s/there/robots/"
hi robots
0. Actually
$ echo "hello there" | sed "s/hello/hi/" | sed "s/there/robots/"
hi robots
1 does two things:

  • It creates a file named
    $ echo "hello there" | sed "s/hello/hi/" | sed "s/there/robots/"
    hi robots
    
    0 if it doesn’t exist; and
  • it replaces
    $ echo "hello there" | sed "s/hello/hi/" | sed "s/there/robots/"
    hi robots
    
    0’s contents with the new contents

So if

$ echo "hello there" | sed "s/hello/hi/" | sed "s/there/robots/"
hi robots
0 already existed, and we did
$ echo "hello there" | sed "s/hello/hi/" | sed "s/there/robots/"
hi robots
5, it would now have only
$ echo "hello there" | sed "s/hello/hi/" | sed "s/there/robots/"
hi robots
6 in it. If you want to append to the file, rather than replacing its contents, you can use the
$ echo "hello there" | sed "s/hello/hi/" | sed "s/there/robots/"
hi robots
7 operator:

$ cat new-file
hello
$ echo hello again >> new-file
$ cat new-file
hello
hello again

File descriptors

A file descriptor, or FD, is a positive integer that refers to an input/output source. For example, stdin is 0, stdout is 1, and stderr is 2. Those might seem like arbitrary numbers, because they are: the POSIX standard defines them as such, and many operating systems (like OS X and Linux) implement at least this part of the POSIX standard.

To duplicate output to a file descriptor, use the

$ echo "hello there" | sed "s/hello/hi/" | sed "s/there/robots/"
hi robots
8 operator plus the FD number. For example:

# Redirect stdout to stdout (FD 1)
$ echo "hello there" >&1
hello there
# Redirect stdout to stderr (FD 2)
$ echo "hello there" >&2
hello there

This is very similar to redirecting output to a file, as we did above, but you can think of stdout and friends as special files that require us to use

$ echo "hello there" | sed "s/hello/hi/" | sed "s/there/robots/"
hi robots
8 instead of
$ echo "hello there"
hello there
$ echo "hello there" | sed "s/hello/hi/"
hi there
8.

Visually all of the output above looks the same, but the changes become apparent when we start piping output. Let’s see what happens when we redirect to stdout versus when we redirect to stderr:

# Redirect to stdout, so it comes through the pipe
$ echo "no changes" >&1 | sed "s/no/some/"
some changes
# Redirect to stderr, so it does not come through
$ echo "no changes" >&2 | sed "s/no/some/"
no changes

ZSH users, take note!

If you’re using ZSH, you may have already noticed slightly different results.

This is due to ZSH’s

$ cat does-not-exist
cat: does-not-exist: No such file or directory
1 option, which is on by default. The
$ cat does-not-exist
cat: does-not-exist: No such file or directory
1 option means that
$ cat does-not-exist
cat: does-not-exist: No such file or directory
3 will output to FD 1 and pipe the output to
$ cat does-not-exist
cat: does-not-exist: No such file or directory
4, rather than only piping it. To turn this off, run
$ cat does-not-exist
cat: does-not-exist: No such file or directory
5.

Here’s what the output of ZSH with the

$ cat does-not-exist
cat: does-not-exist: No such file or directory
1 option looks like:

$ cat
hello there
hello there
say it again
say it again
[ctrl+d]
0

For this blog post, I’ll assume you’re using bash, or have ZSH with the

$ cat does-not-exist
cat: does-not-exist: No such file or directory
1 option unset.

Advanced file descriptors

Let’s say you have stderr output mingled with stdout output – perhaps you’re running the same command over many files, and the command may output to stdout or stderr each time. For convenience, the command outputs “stdout” to stdout, and “stderr” to stderr, plus the file name. The visual output looks like this:

$ cat
hello there
hello there
say it again
say it again
[ctrl+d]
1

We want to transform every line to have “Robot says: ” before it, but just piping the command to sed won’t work, because (again) pipes only grab stdout:

$ cat
hello there
hello there
say it again
say it again
[ctrl+d]
2

This is a common use case for file descriptors: redirect stderr to stdout to combine stderr and stdout, so you can pipe everything as stdout to another process.

Let’s try it:

$ cat
hello there
hello there
say it again
say it again
[ctrl+d]
3

It worked! We successfully redirected stderr (FD 2) into stdout (FD 1), combining them and sending the combined output through stdout.

Common use cases

We could further redirect that combined output to a file, to review the combined output later at our leisure:

$ cat
hello there
hello there
say it again
say it again
[ctrl+d]
4

Neat: we’ve captured both stderr and stdout in a file. One interesting point is that we need to do this:

$ cat
hello there
hello there
say it again
say it again
[ctrl+d]
5

and not this:

$ cat
hello there
hello there
say it again
say it again
[ctrl+d]
6

The correct version points stdout at the log file, then redirects stderr to stdout, so both stderr and stdout point at the log file. The wrong version points stderr at stdout (which outputs to the shell), then redirects stdout to the file. Thus only stdout is pointing at the file, because stderr is pointing to the “old” stdout.

Another common use for redirecting output is redirecting only stderr. To redirect a file descriptor, we use

$ cat does-not-exist
cat: does-not-exist: No such file or directory
8, where N is a file descriptor. If there’s no file descriptor, then stdout is used, like in
$ echo "hello there" | sed "s/hello/hi/" | sed "s/there/robots/"
hi robots
5.

We can use this new syntax to silence stderr by redirecting it to

$ cat does-not-exist | sed 's/No such/ROBOT SMASH/'
cat: does-not-exist: No such file or directory
0, which happily swallows whatever it receives and does nothing with it. It’s the black hole of input/output. Let’s try it:

$ cat
hello there
hello there
say it again
say it again
[ctrl+d]
7

Excellent.

Further reading

Peteris Krumins wrote an excellent blog post about bash redirection and goes into more detail on custom file descriptors.

Which symbol should I use to redirect the error output to the standard output Linux?

2> is input redirection symbol and syntax is:.
To redirect stderr (standard error) to a file: command 2> errors.txt..
Let us redirect both stderr and stdout (standard output): command &> output.txt..
Finally, we can redirect stdout to a file named myoutput.txt, and then redirect stderr to stdout using 2>&1 (errors.txt):.

Which symbol should I use to redirect the standard output to a file?

Redirecting output to append to a file When the notation > > filename is added to the end of a command, the output of the command is appended to the specified file name, rather than writing over any existing data. The >> symbol is known as the append redirection operator.

What is the use of 2 >& 1?

The expression 2>&1 copies file descriptor 1 to location 2 , so any output written to 2 ("standard error") in the execution environment goes to the same file originally described by 1 ("standard output").

What is redirecting standard output?

Input/Output (I/O) redirection in Linux refers to the ability of the Linux operating system that allows us to change the standard input ( stdin ) and standard output ( stdout ) when executing a command on the terminal. By default, the standard input device is your keyboard and the standard output device is your screen.