Skip to content

Linux redirections (stdin and stdout)

Another important concept is redirection. Since Linux was created by programmers for programmers, it was necessary for commands and processes to have the ability to handle data inputs and outputs with great ease. Linux Drivers are the way programs talk to each other through data inputs and outputs.

Before we go into detail about Linux’s redirection ability we need to define what are standard inputs, standard output, and error output:

  • Standard Input (stdin) is the input to a text flow. Examples include the keyboard, the mouse, a floppy disk, etc. All of them feed the computer with information. It can be represented by the number 0.
  • Standard Output (stdout) is the output of a text flow under normal conditions. Examples include the monitor, printer, floppy disk, file, etc. All of them receive information from the computer. It can be represented by the number 1.
  • Error Output (stderr) is the output of a text flow under conditions of error or failure in a particular processing. The error output may be directed to the monitor or to a LOG file. It can be represented by the number 2.

You can view these data streams in the /dev directory with the command:

$ ls -l /dev/std * lrwxrwxrwx 1 root 15 Aug 15 10:53 /dev/stderr -> /proc/self/fd/2 lrwxrwxrwx 1 root root 15 Aug 15 10:53 /dev/stdin -> /proc/self/fd/0 lrwxrwxrwx 1 root root 15 Aug 15 10:53 /dev/stdout -> /proc/self/fd/0 FD/1

As you can see, the /dev/stderr file is a symbolic link to a file in /proc/self/fd/2. The /dev/stdin file points to /proc/self/fd/0 and /dev/stdout to /proc/self/fd/1.

The /proc/self directory is a representation of the Kernel to provide information about the running process. In this special pseudo-directory it is possible to access various information about the process that is currently running. The /proc/self/fd directory is also an abstraction containing file descriptors, which is another abstraction that Linux and Unix make to represent an input or output resource through a file. It’s the way programmers found to provide easy access for data entry and exit.

That’s why stderr is represented by number 2, stdin by number 0, and stdout by 1.

It’s because of file descriptors that we can redirect the standard input or standard output of a given process’s dataflow to another process or a file very easily.

To redirect a result from an output to a data input or file, we use the larger “>” sign.

And to direct a file as a data entry we use the minor sign ”<”.

The double “>>” sign means adding something, usually at the end of a file, without overwriting its content.

And the double sign <<word generally serves to allow the user to enter data by typing into the terminal, until the indicated word is typed, since the word works as a delimiter.

The ”&” sign can be used to join the outputs as in 2>&1.

We can still redirect an output to an entrance using a special vertical bar, the sign in English called “pipe” ”|” or duct.

And the processes can be connected to the 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 the “dumb” terminals through serial cards and connections, represented by the files /dev/ttys N, where& nbsp; N was the number of the terminal to which the user would be connected.

Thus, Linux terminals are represented by file descriptors in the /dev/ directory with a tty prefix:

$ ls -1 /dev/tty * /dev/tty /dev/tty0 /dev/tty1 (...)

Linux maintains the terminals, but in a virtual form, which can be accessed with the combination of Ctrl-Alt-F1, Ctrl-Alt-F2 and Ctrl-Alt-F6 keys, both in a graphic environment and in a text environment.

The “ps -a” command 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 the tty2 terminal.

In the example, the “ps” command is not tied to a tty, but to the pts.

The term pts comes from Pseudo-Terminal, which is nothing more than a tty terminal emulated by a program, such as SSH. Then the programs running through a remote connection will be tied to a fake terminal called pts.

There is also the tty command, which returns which terminal the shell process is linked to, whether it is a real (tty) or emulated (pts) terminal:

$ tty /dev/pts/0

Using this premise, it’s simple to manipulate devices on Linux through the file descriptors in the /dev/ directory.

For example, it is possible to send a message to a remote user connected via ssh in a terminal. To do this, you just need to know which terminal it is connected to with the w command:

$ <a data-id="884" data-type="post" href="https://www.linuxcertification.academy/do-you-know-the-who-command/">w</a>
23:40:41 up 1 day, 17:57, 2 users, load average: 0.00, 0.02, 0.02
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
Arthur pts/0 10.211.55.2 10:31 1:52 0.28s 0.28s -bash
uiraribeiro pts/1 10.211.55.2 23:36 1.00s 0.03s 0.00s w

In this way, you can send a message to Arthur on pts/0, using the echo command 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 and save the result to the saída.txt file:

$ ls > saida.txt

Redirection is mainly used by programs or when the result of processing will not be directly observed by the user in the terminal, but sent to another program, to a file, or to a device.

Here the mail program takes the e-mail address as an argument and instead of using the keyboard as standard input, the text file e-mail.txt is redirected to the mail program in its standard entry with the sign “<”:

$ mail [email protected] < e-mail.txt

To send all the output of the payroll program to file1, including errors:

$. /payroll > file1

It is possible to filter only the standard payroll program output for file1, WITHOUT errors, using only the descriptor “1”:

$. /payroll 1 > file1

If we want to send all the error output to the file file_ erro.log, we can use the descriptor “2”:

. /payroll 2 > arquivo_erro.log

Both standard output and errors can be sent in combination to file file1, using “2>&1” or “1>&2” (the order makes no difference):

$. /payroll > file1 2>&1

It is also possible to separate the outputs into different files, sending the result with the normal output to arquivo_sucesso.log and the error output to the arquivo_erro.log.

$. /payroll 1 > arquivo_sucesso.log 2> arquivo_erro.log

Another possibility is to send only error output to limbo using the /dev/null abstraction:

$. /payroll 2 > /dev/null

The same can be done to send errors to the printer, using the abstraction representing printers in /dev/lp0:

$. /payroll 2 > /dev/lp0

Every time you want to send the standard output of one program to the standard input of another program, you need to use a conductor with the “|” sign on the keyboard.

In this example, the result of the payroll program is sent as input to the program print_bills and the error output from print_bills to the file erro.log:

$. /payroll | print_tickets 2> erros.log

To send an email from the terminal containing 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 the standard input of a command, you can use the “<<word”. In this way, the terminal will receive a text from the keyboard, until the word “end” is typed in one line:

$ mail [email protected] -s urgent < Hello, > This is a test email > end

It is common for Linux to redirect error output to the special file descriptor /dev/null. This special file is the Linux limbo, where everything that goes there disappears:

$ find/-name file 2>/dev/null

This way, the errors found by the find will not be shown in the terminal, only the standard output.