Categorías: Linux

¿Qué son stdin, stdout y stderr en Linux?

Fatmawati Achmad Zaenuri / Shutterstock.com

stdin,, stdouty stderrson tres flujos de datos que se crean al iniciar un comando de Linux. Puede usarlos para saber si sus scripts se están canalizando o redirigiendo. Te mostramos cómo.

Las corrientes unen dos puntos

Tan pronto como empiece a aprender sobre Linux y Unix-como sistemas operativos, que vendrá a través de los términos stdin, stdouty stederr. Estos son tres flujos estándar que se establecen cuando se ejecuta un comando de Linux. En informática, un flujo es algo que puede transferir datos. En el caso de estos flujos, esos datos son texto.

Las corrientes de datos, como las corrientes de agua, tienen dos extremos. Tienen una fuente y una salida. Cualquiera que sea el comando de Linux que esté utilizando, proporciona un extremo de cada flujo. El otro extremo lo determina el shell que lanzó el comando. Ese extremo se conectará a la ventana de la terminal, se conectará a una tubería o se redirigirá a un archivo u otro comando, de acuerdo con la línea de comando que lanzó el comando.

Las transmisiones estándar de Linux

En Linux,  stdines el flujo de entrada estándar. Esto acepta texto como entrada. La salida de texto del comando al shell se envía a través del stdoutflujo (salida estándar). Los mensajes de error del comando se envían a través del stderrflujo (error estándar).

Así se puede ver que hay dos corrientes de salida, stdouty stderr, y un flujo de entrada, stdin. Debido a que los mensajes de error y la salida normal tienen cada uno su propio conducto para llevarlos a la ventana de la terminal, se pueden manejar de forma independiente entre sí.

Las transmisiones se manejan como archivos

Los flujos en Linux, como casi todo lo demás, se tratan como si fueran archivos. Puede leer texto de un archivo y puede escribir texto en un archivo. Ambas acciones involucran un flujo de datos. Entonces, el concepto de manejar un flujo de datos como un archivo no es tan exagerado.

A cada archivo asociado con un proceso se le asigna un número único para identificarlo. Esto se conoce como descriptor de archivo. Siempre que se requiera realizar una acción en un archivo, el descriptor de archivo se utiliza para identificar el archivo.

Estos valores se utilizan siempre para stdin, stdout,y stderr:

  • : stdin
  • 1 : salida estándar
  • 2 : stderr

Reacción a tuberías y redireccionamientos

Para facilitar la introducción de alguien a un tema, una técnica común es enseñar una versión simplificada del tema. Por ejemplo, con la gramática, se nos dice que la regla es «I antes de E, excepto después de C.» Pero en realidad, hay más excepciones a esta regla que casos que la obedecen.

De manera similar, cuando se habla de stdin, stdouty stderr es conveniente sacar a relucir el axioma aceptado de que un proceso ni sabe ni le importa dónde terminan sus tres corrientes estándar. ¿Debería importarle a un proceso si su salida va a la terminal o si se redirige a un archivo? ¿Puede incluso saber si su entrada proviene del teclado o se está canalizando desde otro proceso?

En realidad, un proceso lo sabe, o al menos puede averiguarlo, si decide comprobarlo, y puede cambiar su comportamiento en consecuencia si el autor del software decide agregar esa funcionalidad.

Podemos ver este cambio de comportamiento con mucha facilidad. Prueba estos dos comandos:

ls

ls | gato

El lscomando se comporta de manera diferente si su salida ( stdout) se canaliza a otro comando. Es  lsque cambia a una salida de una sola columna, no es una conversión realizada por cat. Y lshace lo mismo si se redirige su salida:

ls> capture.txt

captura de gato.txt

Redirigir stdout y stderr

Existe la ventaja de tener mensajes de error entregados por una transmisión dedicada. Significa que podemos redirigir la salida de un comando ( stdout) a un archivo y aún ver cualquier mensaje de error ( stderr) en la ventana de terminal. Puede reaccionar a los errores si es necesario, a medida que ocurren. También evita que los mensajes de error contaminen el archivo al que stdoutse ha redirigido.

Escriba el siguiente texto en un editor y guárdelo en un archivo llamado error.sh.

#! / bin / bash

echo "A punto de intentar acceder a un archivo que no existe"
cat bad-filename.txt

Haga que el script sea ejecutable con este comando:

chmod + x error.sh

La primera línea del script envía el texto a la ventana de la terminal, a través de la  stdoutsecuencia. La segunda línea intenta acceder a un archivo que no existe. Esto generará un mensaje de error que se envía a través de stderr.

Ejecute el script con este comando:

./error.sh

Podemos ver que ambos flujos de salida stdouty stderr, se han mostrado en las ventanas de la terminal.

Intentemos redirigir la salida a un archivo:

./error.sh> capture.txt

El mensaje de error que se envía a través de stderrtodavía se envía a la ventana del terminal. Podemos verificar el contenido del archivo para ver si la stdout salida fue al archivo.

captura de gato.txt

La salida de stdinse redirigió al archivo como se esperaba.

El >símbolo de redirección funciona stdoutde forma predeterminada. Puede utilizar uno de los descriptores de archivo numéricos para indicar qué flujo de salida estándar desea redirigir.

Para redirigir explícitamente  stdout, use esta instrucción de redirección:

1>

Para redirigir explícitamente  stderr, use esta instrucción de redirección:

2>

Intentemos nuestra prueba nuevamente, y esta vez usaremos 2>:

./error.sh 2> capture.txt

El mensaje de error se redirige y el stdout echomensaje se envía a la ventana del terminal:

Veamos qué hay en el archivo capture.txt.

captura de gato.txt

El stderrmensaje está en capture.txt como se esperaba.

Redirigiendo tanto stdout como stderr

Seguramente, si podemos redirigir uno stdouto stderrun archivo independientemente el uno del otro, ¿deberíamos poder redirigirlos a ambos al mismo tiempo, a dos archivos diferentes?

Si podemos. Este comando lo dirigirá stdouta un archivo llamado capture.txt y stderra un archivo llamado error.txt.

./error.sh 1> capture.txt 2> error.txt

Debido a que ambos flujos de salida, salida estándar y error estándar, se redirigen a archivos, no hay una salida visible en la ventana del terminal. Regresamos a la línea de comandos como si no hubiera ocurrido nada.

Revisemos el contenido de cada archivo:

captura de gato.txt
cat error.txt

Redirigir stdout y stderr al mismo archivo

Eso es genial, tenemos cada uno de los flujos de salida estándar yendo a su propio archivo dedicado. La única otra combinación que podemos hacer es enviar ambos stdouty stderral mismo archivo.

Podemos lograr esto con el siguiente comando:

./error.sh> capture.txt 2> & 1

Analicemos eso.

  • ./error.sh : inicia el archivo de script error.sh.
  • > capture.txt : redirige la stdoutsecuencia al archivo capture.txt. >es la abreviatura de 1>.
  • 2> & 1 : Utiliza la instrucción de redireccionamiento &>. Esta instrucción le permite decirle al shell que haga que un flujo llegue al mismo destino que otro flujo. En este caso, estamos diciendo «redirigir la secuencia 2, stderral mismo destino al que stdoutse redirige la secuencia 1 «.

No hay salida visible. Eso es alentador.

Revisemos el archivo capture.txt y veamos qué contiene.

captura de gato.txt

Tanto el stdouty stderrcorrientes han sido redirigidos a un solo archivo de destino.

Para que la salida de un flujo se redirija y se deseche silenciosamente, dirija la salida a /dev/null.

Detección de redireccionamiento dentro de un script

Discutimos cómo un comando puede detectar si alguna de las transmisiones está siendo redirigida y puede optar por modificar su comportamiento en consecuencia. ¿Podemos lograr esto en nuestros propios guiones? Si podemos. Y es una técnica muy fácil de entender y emplear.

Escriba el siguiente texto en un editor y guárdelo como input.sh.

#! / bin / bash

si [-t 0]; luego

  echo stdin procedente del teclado
 
más

  echo stdin procedente de una tubería o un archivo
 
fi

Utilice el siguiente comando para hacerlo ejecutable:

chmod + x input.sh

La parte inteligente es la prueba entre corchetes . La -topción (terminal) devuelve verdadero (0) si el archivo asociado con el descriptor de archivo  termina en la ventana de la terminal . Hemos utilizado el descriptor de archivo 0 como argumento de la prueba, que representa   stdin.

Si stdinestá conectado a una ventana de terminal, la prueba será cierta. Si stdinestá conectado a un archivo o tubería, la prueba fallará.

Podemos usar cualquier archivo de texto conveniente para generar entradas para el script. Aquí estamos usando uno llamado dummy.txt.

./input.sh <dummy.txt

La salida muestra que el script reconoce que la entrada no proviene de un teclado, sino de un archivo. Si lo desea, puede variar el comportamiento de su script en consecuencia.

Eso fue con una redirección de archivos, intentémoslo con una tubería.

cat dummy.txt | ./input.sh

El script reconoce que su entrada se canaliza a él. O más precisamente, reconoce una vez más que la stdintransmisión no está conectada a una ventana de terminal.

Ejecutemos el script sin canalizaciones ni redireccionamientos.

./input.sh

La stdintransmisión está conectada a la ventana de la terminal y el script lo informa en consecuencia.

Para comprobar lo mismo con el flujo de salida, necesitamos un nuevo script. Escriba lo siguiente en un editor y guárdelo como output.sh.

#! / bin / bash

si [-t 1]; luego

echo stdout va a la ventana de terminal
 
más

echo stdout está siendo redirigido o canalizado
 
fi

Utilice el siguiente comando para hacerlo ejecutable:

chmod + x input.sh

El único cambio significativo en este script está en la prueba entre corchetes. Estamos usando el dígito 1 para representar el descriptor de archivo stdout.

Probémoslo. Canalizaremos la salida cat.

./output | gato

El script reconoce que su salida no va directamente a una ventana de terminal.

También podemos probar el script redireccionando la salida a un archivo.

./output.sh> capture.txt

No hay salida en la ventana del terminal, se nos devuelve silenciosamente al símbolo del sistema. Como era de esperar.

Podemos mirar dentro del archivo capture.txt para ver qué se capturó. Utilice el siguiente comando para hacerlo.

captura de gato.sh

Nuevamente, la prueba simple en nuestro script detecta que la stdouttransmisión no se envía directamente a una ventana de terminal.

Si ejecutamos el script sin canalizaciones ni redirecciones, debería detectar que stdoutse está enviando directamente a la ventana de la terminal.

./output.sh

Y eso es exactamente lo que vemos.

Corrientes de conciencia

Saber cómo saber si sus scripts están conectados a la ventana de la terminal, o una tubería, o si están siendo redirigidos, le permite ajustar su comportamiento en consecuencia.

La salida de registro y diagnóstico puede ser más o menos detallada, dependiendo de si va a la pantalla oa un archivo. Los mensajes de error se pueden registrar en un archivo diferente al de la salida normal del programa.

Como suele ser el caso, un mayor conocimiento trae más opciones.

responroot

Compartir
Publicado por
responroot
Etiquetas: linux

Entradas recientes

Steamlytics: La nueva herramienta imprescindible para los gamers de Steam

  El mundo del gaming ha experimentado un crecimiento exponencial en los últimos años. La…

1 año hace

Cuándo reemplazar su antigua unidad flash USB

Stokkete/Shutterstock.com ¿Sigue utilizando una unidad flash USB obsoleta para almacenar sus archivos? ¿Por qué no…

3 años hace

¿Qué es una pantalla Nano IPS?

LG Los fabricantes siempre intentan mejorar el rendimiento de imagen de los monitores. Como resultado,…

3 años hace

10 formas de jugar con un presupuesto bajo (o nulo)

Patty Chan/Shutterstock.com Si cree en lo que ve en las redes sociales, puede pensar en…

3 años hace

¿Demasiadas suscripciones? Aquí está cómo empezar a cortarlos

Seksan.TH/Shutterstock.com Los servicios de suscripción como Netflix, Game Pass y Spotify nos permiten consumir tantas…

3 años hace

Cómo configurar la puerta de enlace predeterminada en Linux

fatmawati achmad zaenuri/Shutterstock El acceso a Internet, oa cualquier otra red, se rige por la…

3 años hace