What Is stdin, stdout, and stderr in Linux

What Is stdin, stdout, and stderr in Linux

When a Linux command reads text you type, sends results to the terminal, or prints an error beside them, it is using a set of connections prepared before the program starts. These connections are standard input, standard output, and standard error, usually shortened to stdin, stdout, and stderr.

The shell can connect these streams to a terminal, file, pipe, or another destination without changing the program itself. This guide explains what the three standard streams do, why they use file descriptors 0, 1, and 2, and how shell redirection changes their destinations.

The Three Standard Streams

A process normally starts with three open file descriptors inherited from its parent. When you launch a command from an interactive shell, the shell usually connects all three to your current terminal:

Stream File descriptor Purpose Interactive default
stdin 0 Input read by the program Terminal input
stdout 1 Normal program output Terminal display
stderr 2 Errors and diagnostic messages Terminal display

Describing stdin as the keyboard is a useful shortcut, but the program actually reads from a terminal device. The terminal handles keyboard input and passes it to the program. In a script or pipeline, stdin may instead come from a file or another command.

The numbers matter because shell redirection syntax uses them. stdout and stderr both appear on the terminal by default, so they can look like one stream even though they remain separate. A script can save normal results in one file while sending errors somewhere else.

Seeing stdout and stderr Separately

The following commands print one normal message and one warning:

Terminal

printf '%s\n' "backup complete"
printf '%s\n' "warning: archive not found" >&2

output

backup complete
warning: archive not found

Both lines appear in the same terminal, but they traveled through different streams. The first printf writes to stdout. The >&2 redirection sends the second command’s output to stderr, which lets a script report a diagnostic without mixing it into data that another command may need to process.

Changing Stream Destinations

The shell sets up redirections before it starts the command. The program continues reading and writing the same file descriptors without needing to know whether they point to a terminal, file, or pipe.

The > operator sends stdout to a file, creating the file or replacing its contents:

Terminal

ls /etc > files.txt

Nothing appears on the terminal because the directory listing went to files.txt. Since > uses stdout when no descriptor is specified, > files.txt and 1> files.txt have the same effect.

stderr remains connected to the terminal unless you redirect descriptor 2. This command requests one existing path and one missing path:

Terminal

ls /etc /nonexistent > files.txt

output

ls: cannot access '/nonexistent': No such file or directory

The successful listing went into files.txt, while the error stayed visible because it traveled through stderr. Redirect descriptor 2 to capture it separately:

Terminal

ls /etc /nonexistent > files.txt 2> errors.txt

Now normal results are in files.txt and the diagnostic is in errors.txt.

To save both streams in one file using portable shell syntax, redirect stdout first and then duplicate its destination for stderr:

Terminal

command > output.log 2>&1

The 2>&1 expression makes file descriptor 2 point to the current destination of file descriptor 1. Redirections are processed from left to right, so reversing their order produces a different result. See how to redirect stderr to stdout in Bash
for combining, appending, piping, and discarding output.

Input redirection works in the other direction. The < operator connects a file to stdin:

Terminal

sort < names.txt

Here sort reads from names.txt instead of the terminal. Many commands also accept a filename as an argument, but input redirection works for any command designed to read from stdin.

How Pipes Use the Streams

A pipe (|) connects the stdout of one command to the stdin of the next, so data can move between programs without a temporary file:

Terminal

ls /etc | grep conf

The stdout of ls becomes the stdin of grep. A regular pipe carries stdout, not stderr, so an error from ls still appears on the terminal instead of passing to grep. The Linux pipes guide
covers longer pipelines, error handling, and pipefail. To show output on the terminal while also saving it, use the tee command
.

Quick Reference

For a printable quick reference, see the Bash cheatsheet
.

Descriptor or syntax Effect
0 stdin
1 stdout
2 stderr
command < file Read stdin from file
command > file Write stdout to file, replacing its contents
command >> file Append stdout to file
command 2> file Write stderr to file
command > file 2>&1 Write stdout and stderr to the same file
command 2>/dev/null Discard stderr
cmd1 | cmd2 Connect stdout from cmd1 to stdin for cmd2

Conclusion

When a command sends data somewhere unexpected, identify whether it is using file descriptor 0, 1, or 2, then read its redirections from left to right. That habit makes shell pipelines and logging commands much easier to follow.

By admin

Leave a Reply