fbpx Pipes y Redirecciones en Linux: |, >, >> y 2>&1 | Certificação Linux

Conductores en Linux: stdin, stdout, stderr, pipes y redirecciones

📅 01/01/2019 ⏱ 9 min ✍️ Uira Ribeiro
Linuxcomandos
Conductores en Linux: stdin, stdout, stderr, pipes y redirecciones
Exam Pass App — mais de 7.000 questões LPI, offline, em 5 idiomas, disponível no Android e na App Store
Disponible en
Google Play
Disponible en
App Store

Outro conceito importante é o redirecionamento. Como o Linux foi criado por programadores para programadores, fez-se necessário que os comandos e processos tivessem a habilidade de tratar as entradas e saídas de dados com grande facilidade. Os Condutores no Linux são a forma como os programas conversam entre si através das entradas e saídas de dados.

Antes de detallarmos a habilidade de redirecionamento do Linux precisamos definir o que são entradas padrão, saída padrão e saída de erro:

  • A Entrada Padrão (stdin) é a entrada de um fluxo de texto. Como exemplos temos o teclado, o mouse, um disquete, etc. Todos eles alimentam o computador com informações. Pode ser representado pelo número 0.
  • A Saída Padrão (stdout) é a saída de um fluxo de texto em condições normais. Como exemplos temos o monitor, a impressora, o disquete, um arquivo, etc. Todos eles recebem informações do computador. Pode ser representado pelo número 1.
  • A Saída de Erro (stderr) é a saída de um fluxo de texto em condições de erro ou insucesso em um determinado processamento. A saída de erro poderá ser direcionada para o monitor ou para um arquivo de LOG. Pode ser representado pelo número 2.

Você pode ver esses fluxos de dados no diretório /dev com o comando:

$ 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

Como você pode perceber, o arquivo /dev/stderr é um link simbólico para um arquivo no /proc/self/fd/2. O arquivo /dev/stdin aponta para o /proc/self/fd/0 e /dev/stdout para /proc/self/fd/1.

O diretório /proc/self é uma representação do Kernel para dar informações sobre o processo em execução. Neste pseudo-diretório especial é possível acessar várias informações sobre o processo que está sendo executado no momento. O diretório /proc/self/fd é também uma abstração que contém os descritores de arquivos (file descriptors), que é outra abstração que o Linux e o Unix fazem para representar através de um arquivo um recurso de entrada ou saída de dados. É a forma que os programadores encontraram de dar acesso fácil para entrada e saída de dados.

É por isso que o stderr é representado pelo número 2, o stdin pelo número 0 e o stdout pelo 1.

É por causa dos descritores de arquivos que podemos redirecionar a entrada padrão ou a saída padrão do fluxo de dados de um determinado processo para outro processo ou um arquivo com muita facilidade.

Para redirecionar um resultado de uma saída para uma entrada de dados ou arquivo utilizamos o sinal de maior ">".

E para direcionarmos algum arquivo como uma entrada de dados usamos o sinal de menor "<". 

O sinal duplo ">>" significa adicionar algo, geralmente ao final de um arquivo, sem sobrescrever o seu conteúdo. 

E o sinal duplo <<palavra geralmente serve para permitir que o usuário entre com dados digitando no terminal, até que a palavra indicada seja digitada, uma vez que a palavra funciona como um delimitador.

O sinal "&" pode ser usado para juntar as saídas como em 2>&1.

Todavía podemos redireccionar una salida para una entrada usando una barra vertical especial, el sinal em inglês chamado "pipe" "|" ou duto. 

Y los processos podem estar ligados aos terminais, conhecidos como tty. El término tty deriva de la palabra Teletype. 

Nos primórdios do Linux, o administrador utilizava o terminal principal do computador, que era representado pelo arquivo /dev/console e os usuários eram ligados aos terminais "burros" através de placas e conexões seriais, representados pelos arquivos /dev/ttySN, onde N era o número do terminal ao qual o usuário estaria ligado.

Assim, terminais no Linux são representados pelos descritores de arquivos no diretório /dev/ com prefixo tty:

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

O Linux mantém os terminais, mas de forma virtual, que podem ser acessados com a combinação de teclas Ctrl-Alt-F1, Ctrl-Alt-F2 até Ctrl-Alt-F6, tanto em ambiente gráfico como em ambiente texto.

O comando "ps -a" pode mostrar quais processos estão conectados a quais terminais:

$ 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

Observe que o ambiente gráfico está atrelado ao terminal tty2.

No exemplo o comando "ps" não está atrelado a um tty, mas ao pts.

O termo pts vem de Pseudo-Terminal, que nada mais é do que um terminal tty emulado por um programa, como, por exemplo, o ssh. Então os programas em execução através de uma conexão remota, estarão atrelados a um terminal falso denominado pts.

Também existe o comando tty, que devuelve qual é o terminal que o processo do shell está atrelado, seja ele um terminal real (tty) ou emulado (pts):

$ tty /dev/pts/0

Usando essa premissa, é simples manipular dispositivos no Linux através dos descritores de arquivos no diretório /dev/.

Por exemplo, é possível mandar uma mensagem para um usuário remoto conectado via ssh num terminal. Para isto, basta saber qual é o terminal que ele está conectado com o comando 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

Desta forma, pode-se mandar uma mensagem para o Arthur no pts/0, utilizando o comando echo seguido do redirecionador ">" e o descritor de arquivos que representa o pseudo-terminal pts/0:

$ echo "Hello" > /dev/pts/0

Qualquer comando pode ter a sua saída redirecionada para um arquivo, ou para um dispositivo utilizando um descritor de arquivos que o representa.

No exemplo seguinte listamos os arquivos num diretório gravando o resultado no arquivo saída.txt :

$ ls > saida.txt 

O redirecionamento é utilizado principalmente por programas ou quando o resultado de um processamento não será observado diretamente pelo usuário no terminal, mas enviado para outro programa, para um arquivo ou para um dispositivo. 

Aqui o programa mail recebe como argumento o endereço de e-mail e ao invés de utilizarmos o teclado como entrada padrão, redireciona-se o arquivo texto e-mail.txt para o programa mail na entrada padrão dele com o sinal "<":

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

Para enviar toda a saída do programa folha_pagamento para o arquivo1, inclusive com os erros:

$ ./folha_pagamento > arquivo1

É possível filtrar somente a saída padrão do programa folha_pagamento para arquivo1, SEM os erros, usando somente o descritor "1":

$ ./folha_pagamento 1 > arquivo1

Si queremos enviar toda la salida de errores al archivo archivo_error.log, podemos usar el descriptor "2":

./folha_pagamento 2 > arquivo_erro.log

Tanto la salida estándar como los errores pueden ser enviados de forma combinada al archivo archivo1, usando "2>&1" o "1>&2" (no hace diferencia el orden):

$ ./folha_pagamento > arquivo1 2>&1

También es posible separar las salidas en archivos diferentes, enviando el resultado con la salida normal al archivo_exito.log y la salida de error al archivo_erro.log.

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

Otra posibilidad es enviar únicamente la salida de errores al limbo usando la abstracción de /dev/null:

$ ./folha_pagamento 2 > /dev/null

Lo mismo puede hacerse para enviar los errores a la impresora, usando la abstracción que representa impresoras en /dev/lp0:

$ ./folha_pagamento 2 > /dev/lp0

Cada vez que quieras enviar la salida estándar de un programa a la entrada estándar de otro programa, necesitas usar un conducto, con el símbolo "|" del teclado.

En este ejemplo, el resultado del programa hoja_pago se envía como entrada al programa imprime_boletos y la salida de error del imprime_boletos al archivo error.log:

$ ./folha_pagamento | imprime_boletos 2> erros.log

Para enviar un email desde la terminal con el contenido de un archivo, se puede usar el redireccionador "<":

$ mail [email protected] -s urgent < mail.txt

Para recibir datos de la terminal y enviarlos a la entrada estándar de un comando, se puede usar el "<<palabra". De esta forma la terminal recibirá un texto del teclado, hasta que la palabra "fin" sea digitada en una línea:

$ mail [email protected] -s urgent <<fim> Olá,> Este é um email de teste> fim

Es común que Linux redirija la salida de errores al descriptor de archivos especial /dev/null. Este archivo especial es el limbo de Linux, donde todo lo que va ahí desaparece:

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

De esta forma, los errores que el find encuentre no se mostrarán en la terminal, solo la salida estándar.

Aprende mucho más sobre Linux en nuestro curso en línea. Puedes efectivá-la aquí. Si ya tienes una cuenta, o quieres crear una, simplemente inicia sesión o crea tu usuario aquí.

¿Te gustó? Comparte

Uira Ribeiro

Prof. Uirá Ribeiro

Chair do Board do Linux Professional Institute

Después de años viendo profesionales perder horas en tareas simples por no conocer las herramientas correctas de Linux, decidí enseñar.
Hoy soy autor de la mayoría de los Materiales de Aprendizaje oficiales de la LPI y mentor de más de 14,000 alumnos certificados.

Conoce mi historia completa →

Eso fue solo una pieza. El curso enseña el camino completo — desde tu primer comando hasta el día del examen.

Certificação Linux — a plataforma líder em certificações Linux no Brasil
WhatsApp