Standard Input (stdin), Standard Output (stdout) and Standard Error (stderr) are three I/O streams, with standardized file descriptors that in the great majority of the software are used to receive input, deliver the output and/or error information. Since everything in Linux is treated as a file, I/O streams are no exception.

The file descriptors used for these three streams are:

  1. 0, 0<, < - These are used for stdin

  2. 1, 1>, > - These are used for stdout

  3. 2, 2> - These are used for stderr

Usually, when a process starts, it should already have these three streams open because it needs to send data to let the user know what it is doing, and so it will use stdin to accept input and it will send output messages to stdout and “error” output messages to stderr.


The simplest way of thinking about stdin is the input we send from a keyboard inside a shell, it is the data you send to a process (through the shell) which then reads it and acts upon it. Such as sending a command.

This is not the only example, as in Linux we are also allowed to “take” stdin from a file.

cat < text.txt

This uses < (which is shorthand for 0<) so that the stdin is taken from something else than the keyboard writing on your terminal, but directly from text.txt itself, which is the same as simply doing:

cat text.txt

stdout & stderr

With stdout we define an output. It could be the data received as a result of a command, delivered by a process.

In the example of a terminal, the command:

cat text.txt

Would mean that the process originated from a terminal, and so the stdout is sent to the terminal for the user to read.

stdout is redirectable and/or “pipable”, for example:

ls | cat > file.txt

What this does is: take the stdout from the ls command, piping (|) it to cat which then uses its stdout and redirects it to file.txt, in doing so it would create a file with the list (ls) of contents of the folder the terminal is in at any given moment.

stderr logically works in the same way as stdout but is specific to error messages that a process might have to send when it encounters them.

cat filethatdoesntexist.txt

Executing cat on a file that does not exist, would make it generate an error message, the output stream of that message is sent from the file descriptor of the stderr output.

And so doing:

cat filethatdoesntexist.txt 2> errorlog.txt

Would redirect any error messages to the file errorlog.txt instead of sending both stdout and stderr in your terminal.

More use cases

All of these I/O streams can be concatenated to one another with various combinations:

Redirecting stdout and stderr

cat filethatmightexist.txt 1> positive.txt 2> negative.txt

What would this do is output the content of filethatmightexist.txt in positive.txt, while outputting any error messages inside negative.txt because we used 1> (stdout) in the first output file and >2(stderr) in the second output file.

Mixing stdout and stderr

cat filethatmightexist.txt 2&>1 mixed.txt

What would this do is tell your shell to send stderr in the same location as stdout

Redirecting stdin

The same can be done using stdin

cat < file1.txt > file2.txt

This would use the stdin from the contents of file1.txt and redirect them inside file2.txt which is essentially like doing cat file1 > file2 or making a copy of it

Appending from stdout or stderr

Appending is done using double (>>) symbols. This would tell the process to append content in a file instead of replacing it.


These streams can also be “piped” into other commands, as shown previously. As an example using grep:

lsof -i -P -n | grep LISTEN

This command would execute lsof with its flags to have a list of ports on the system, then would use its stdout to pipe it to the grep command which uses a simple search pattern for LISTEN which would grab all lines for ports that are currently listening.

All of this can also be concatenated further:

lsof -i -P -n | grep LISTEN 1>> log.txt 2>> errorlog.txt

This would take the stdin from your keyboard for lsof, use its stdout to pipe it to grep which would filter it using its search pattern and send its own stdout to two different files, appending log messages to the first file and any error message to the second file.

Making a command silent

/dev/null is like a black-hole. Anything sent there, is discarded. With this logic we can decide to send all stdout or stderr there, to make a process be silent.

cat process.log >1 process.txt >2 /dev/null

This would create a file called process.txt with the contents of process.log and just discard any kind of error because stderr was redirected to /dev/null.

Want to support me?

Find all information right here

You can also support me here:


  • My mom
  • Homelabber

Check out The Hall of Fame

You can download the markdown version of this guide from here