Linux Streams: stdin, stdout, stderr, Pipes, and Redirections
Another important concept is redirection. Since Linux was created by programmers for programmers, it became necessary for commands and processes to have the ability to handle data input and output with great ease. Streams in Linux are the way programs communicate with each other through data input and output.
Before we detail Linux's redirection capability, we need to define what standard input, standard output, and error output are:
- The Standard Input (stdin) is the input of a text stream. Examples include the keyboard, mouse, a floppy disk, etc. They all feed the computer with information. It can be represented by the number 0.
- The Standard Output (stdout) is the output of a text stream under normal conditions. Examples include the monitor, printer, floppy disk, a file, etc. They all receive information from the computer. It can be represented by the number 1.
- The Error Output (stderr) is the output of a text stream under error or failure conditions during a certain processing. The error output can be directed to the monitor or to a LOG file. It can be represented by the number 2.
You can see these data streams in the /dev directory with the command:
$ ls -l /dev/std*lrwxrwxrwx 1 root root 15 ago 15 10:53 /dev/stderr -> /proc/self/fd/2lrwxrwxrwx 1 root root 15 ago 15 10:53 /dev/stdin -> /proc/self/fd/0lrwxrwxrwx 1 root root 15 ago 15 10:53 /dev/stdout -> /proc/self/fd/1
As you can see, the file /dev/stderr is a symbolic link to a file in /proc/self/fd/2. The file /dev/stdin points to /proc/self/fd/0 and /dev/stdout to /proc/self/fd/1.
The directory /proc/self is a Kernel representation that provides information about the running process. In this special pseudo-directory, it is possible to access various information about the process being executed at the moment. The directory /proc/self/fd is also an abstraction that contains file descriptors, which is another abstraction that Linux and Unix make to represent an input or output data resource through a file. This is the way programmers found to provide easy access to data input and output.
That's why stderr is represented by the number 2, stdin by the number 0, and stdout by 1.
It's because of file descriptors that we can redirect the standard input or the standard output of a data stream from a certain process to another process or file with great ease.
To redirect an output result to an input of data or file, we use the greater-than sign ">".
And to direct a file as a data input, we use the less-than sign "<".
The double sign ">>" means appending something, usually to the end of a file, without overwriting its content.
And the double sign <<word usually serves to allow the user to enter data by typing in the terminal, until the indicated word is typed, since the word functions as a delimiter.
The sign "&" can be used to join outputs as in 2>&1.
We can also redirect an output to an input using a special vertical bar, the English-called "pipe" "|" or duct.
And processes can be connected to terminals, known as tty. The term tty derives from the word Teletype.
In the early days of Linux, the administrator used the computer's main terminal, which was represented by the file /dev/console and users were connected to "dumb" terminals through serial cards and connections, represented by the files /dev/ttySN, where N was the number of the terminal to which the user would be connected.
Thus, terminals in Linux are represented by file descriptors in the /dev directory with the tty prefix:
$ ls -1 /dev/tty*/dev/tty/dev/tty0/dev/tty1( ... )
Linux maintains terminals, but virtually, which can be accessed with the key combination Ctrl-Alt-F1, Ctrl-Alt-F2 through Ctrl-Alt-F6, both in graphical and text environments.
The command "ps -a" can show which processes are connected to which terminals:
$ ps -a PID TTY TIME CMD 2738 tty2 00:12:41 Xorg 2751 tty2 00:00:00 gnome-session-b 9274 pts/0 00:00:00 ps
Note that the graphical environment is tied to terminal tty2.
In the example, the command "ps" is not tied to a tty, but to pts.
The term pts comes from Pseudo-Terminal, which is nothing more than a tty terminal emulated by a program, such as, for example, ssh. So programs running through a remote connection will be tied to a fake terminal called pts.
There is also the command tty, which returns which terminal the shell process is tied to, whether it's a real (tty) or emulated (pts) terminal:
$ tty /dev/pts/0
Using this premise, it is simple to manipulate devices in Linux through file descriptors in the /dev/ directory.
For example, it is possible to send a message to a remote user connected via ssh on a terminal. To do this, just find out which terminal they are connected to using the command w:
$ w 23:40:41 up 1 day, 17:57, 2 users, load average: 0.00, 0.02, 0.02USER TTY FROM LOGIN@ IDLE JCPU PCPU WHATarthur pts/0 10.211.55.2 10:31 1:52 0.28s 0.28s -bashuiraribe pts/1 10.211.55.2 23:36 1.00s 0.03s 0.00s w
This way, you can send a message to Arthur on pts/0, using the command echo followed by the redirector ">" and the file descriptor that represents the pseudo-terminal pts/0:
$ echo "Hello" > /dev/pts/0
Any command can have its output redirected to a file, or to a device using a file descriptor that represents it.
In the following example we list the files in a directory, saving the result to the file output.txt:
$ ls > saida.txt
Redirection is mainly used by programs or when the result of a processing will not be observed directly by the user at the terminal, but sent to another program, to a file, or to a device.
Here the mail program receives the email address as an argument and instead of using the keyboard as standard input, the text file email.txt is redirected to the mail program's standard input with the "<" sign:
$ mail [email protected] < e-mail.txt
To send all output from the folha_pagamento program to file1, including errors:
$ ./folha_pagamento > arquivo1
It is possible to filter only the standard output of the folha_pagamento program to file1, WITHOUT errors, using only descriptor "1":
$ ./folha_pagamento 1 > arquivo1
If we want to send all error output to the arquivo_erro.log file, we can use the "2" descriptor:
./folha_pagamento 2 > arquivo_erro.log
Both standard output and errors can be sent combined to the arquivo1 file, using "2>&1" or "1>&2" (order doesn't matter):
$ ./folha_pagamento > arquivo1 2>&1
It's also possible to separate the outputs into different files, sending the normal result to arquivo_sucesso.log and the error output to arquivo_erro.log.
$ ./folha_pagamento 1 > arquivo_sucesso.log 2> arquivo_erro.log
Another possibility is to send only error output to the void using the /dev/null abstraction:
$ ./folha_pagamento 2 > /dev/null
The same can be done to send errors to the printer, using the abstraction that represents printers in /dev/lp0:
$ ./folha_pagamento 2 > /dev/lp0
Every time you want to send a program's standard output to another program's standard input, you need to use a pipe, with the "|" symbol from the keyboard.
In this example, the result of the folha_pagamento program is sent as input to the imprime_boletos program, and the error output of imprime_boletos to the erro.log file:
$ ./folha_pagamento | imprime_boletos 2> erros.log
To send an email from the terminal with the contents of a file, you can use the "<" redirector:
$ mail [email protected] -s urgent < mail.txt
To receive data from the terminal and send it to a command's standard input, you can use the "<<word". This way, the terminal will receive text from the keyboard, until the word "end" is typed on a line:
$ mail [email protected] -s urgent <<fim> Olá,> Este é um email de teste> fim
It's common in Linux to redirect error output to the special file descriptor /dev/null. This special file is Linux's void, where everything that goes there disappears:
$ find / -name arquivo 2>/dev/null
This way, the errors that find encounters won't be shown on the terminal, only the standard output.
Learn much more about Linux in our online course. You can enroll here. If you already have an account, or want to create one, just log in or create your user here.
Like it? Share
That was just one piece. The course teaches the whole path — from your first command to exam day.