Understanding Stdin, Stdout, and Stderr Streams in Linux

Linux TLDR
Last Updated:
Reading time: 4 minutes

If you ever used vim, nano, or read commands, you were already using the stdin stream.

Or if you were listing the files and directories from your system using the ls command, you were using the stdout stream.

In case you misspelled your command or interpreted something wrong, you were using the stderr stream.

I mean to say that if you were interacting with a Linux terminal and performing any command execution or piping the two commands, you already had them in use.

Tutorial Details

DescriptionStdin, Stdout, and Stderr Streams
Difficulty LevelModerate
Root or Sudo PrivilegesNo
Host System and ArchitectureUbuntu 22.10 (x64)
OS Compatibility Ubuntu, Manjaro, Fedora, etc.
Prerequisitescat, echo, read, ls
Internet RequiredNo
Discussed Tools in this ArticlePipping and redirection
  • stdin a.k.a. “standard input,” will take the text as input.
  • stdout a.k.a. “standard output,” is the output of a command that is stored in this stream.
  • stderr a.k.a. “standard error,” stores the command error or diagnostic information.

Also, Linux assigns unique values to each of these data streams.

stdin0
stdout1
stderr2

In Linux, you do not need to find this file or perform any action for them; they are already part of your Linux system and attached to your terminal device (e.g., “/dev/tty“).

Whenever you execute any command in your terminal, this stream will sit in the back and watch the command you execute, and then the one that is required will come into use.

For example, if you execute the read command in your terminal, it will ask for input from your keyboard taking the use of stdin stream.

$ read
Hello folks, this is the stdin example from linuxtldr.com

Now, if you were listing the current directory, you would execute the ls command, which would return or stream the data to stdout, and the terminal would print it out.

$ ls -l
total 36
drwxr-xr-x 2 linuxtldr linuxtldr 4096 Nov 16 15:48 Desktop
drwxr-xr-x 2 linuxtldr linuxtldr 4096 Nov 17 22:34 Documents
drwxr-xr-x 2 linuxtldr linuxtldr 4096 Nov 16 15:48 Downloads
drwxr-xr-x 2 linuxtldr linuxtldr 4096 Nov 17 22:19 Music
drwxr-xr-x 2 linuxtldr linuxtldr 4096 Nov 16 15:48 Pictures
drwxr-xr-x 2 linuxtldr linuxtldr 4096 Nov 16 15:48 Public
drwx------ 3 linuxtldr linuxtldr 4096 Nov 16 15:48 snap
drwxr-xr-x 2 linuxtldr linuxtldr 4096 Nov 16 15:48 Templates
drwxr-xr-x 2 linuxtldr linuxtldr 4096 Nov 16 15:48 Videos

However, if I misspell the same command above as shown,

$ ls -l randomstring
ls: cannot access 'randomstring': No such file or directory

Above, I provided an invalid argument to the ls command, which resulted in the “No such file or directory” error that is returned to stderr stream by the ls command.

Piping the Two Commands

Using the stdin, stdout, and, in some cases, stderr can be used to pipe one command output as another command input, and vice versa, using the “|” sign.

For example, you can use the “|” sign to pipe the echo command output (stdout stream) to the grep command (stdin stream) as shown.

$ echo "Hello folks!" | grep Hello
Hello folks!

If you want to pipe stdout and stderr to the next command, use the “|&” instead.

Without error:

$ echo "Hello folks!" |& cat
Hello folks!

With error:

$ randomstring |& cat
randomstring: command not found

Redirecting the Commands

In the above, you learn to pipe two different commands using the “|” sign and redirect stdout or stderr streams’ data to the stdin stream.

However, you can use an “>” sign to write this data into a file or redirect it to the another command as argument.

$ echo "Hello folks!" > file.txt

The above command will take the stdout stream data from the echo command and redirect it to the target file (ex: “file.txt“).

Remember, when you execute the above command in the present directory, if there is no “file.txt“, it will create a fresh file.

But if there is already a file with the same name as the target file in the present directory (ex: “file.txt”), it will overwrite it by removing the present content with new content (“Hello, folks!”) into the file.

However, you can prevent this from happening by using the “>>” double redirection symbol, which will write the stdout stream data at the end of the target file.

$ echo "Hello folks!" >> file.txt
$ cat file.txt
Hello folks!
Hello folks!

However, you can also take the stdin stream data as an input from another command instead of using the keyboard, as shown.

$ cat < file.txt 
Hello folks!
Hello folks!

The above cat command is working as stdin data (without the use of a keyboard) from the file (ex, “file.txt“), which is working as stdout data.

Redirecting the stdout and stderr

Until now, we were redirecting the stdout data to stdin and vice versa. However, you can also redirect the stdout and stderr streams together to the stdin stream using their unique values, as shown.

$ echo "Hello folks!" 1> output.txt 2>errors.txt

The above command will not throw an error, so only stdout data will be redirected to stdin, and “output.txt” will have the following content.

$ cat output.txt 
Hello folks!
$ cat errors.txt

However, if you execute the wrong command or misspell it, as shown.

$ randomcommand 1> output.txt 2>errors.txt

It will only modify the “errors.txt” file with the error message that came from the stderr stream, as shown.

$ cat errors.txt 
randomcommand: command not found

Thatโ€™s all for now. I tried to explain this concept to you as simply as possible for beginners to understand.

They are simply used to stream data from one point to another, much like rivers flow from one end to another.

In case you are unable to understand anything or are still unclear with the concept, do let us know in the comment section.

Join The Conversation

Users are always welcome to leave comments about the articles, whether they are questions, comments, constructive criticism, old information, or notices of typos. Please keep in mind that all comments are moderated according to our comment policy.