¿Confundido acerca de stdin, stdout y stderr?
Estoy bastante confundido con el propósito de estos tres archivos. Si mi comprensión es correcta, stdin
es el archivo en el que un programa escribe en sus solicitudes para ejecutar una tarea en el proceso, stdout
es el archivo en el que el núcleo escribe su salida y el proceso desde el que accede a la información, y stderr
es el archivo en en el que se introducen todas las excepciones. Al abrir estos archivos para comprobar si realmente ocurren, ¡no encontré nada que pareciera sugerirlo!
Lo que me gustaría saber es cuál es exactamente el propósito de estos archivos, ¡una respuesta absolutamente tonta con muy poca jerga tecnológica!
Entrada estándar|STDIN : este es el identificador de archivo que lee su proceso para obtener información suya.
Salida estándar|STDOUT : su proceso escribe la salida convencional en este identificador de archivo.
Error estándar|STDERR : su proceso escribe la salida de diagnóstico en este identificador de archivo.
Eso es lo más tonto que puedo hacer :-)
Por supuesto, eso es principalmente por convención. No hay nada que le impida escribir su información de diagnóstico en la salida estándar si lo desea. Incluso puedes cerrar completamente los tres identificadores de archivos y abrir tus propios archivos para E/S.
Cuando comience su proceso, ya debería tener estos identificadores abiertos y simplemente puede leerlos y/o escribirles.
De forma predeterminada, probablemente estén conectados a su dispositivo terminal (por ejemplo, /dev/tty
), pero los shells le permitirán configurar conexiones entre estos identificadores y archivos y/o dispositivos específicos (o incluso canalizaciones a otros procesos) antes de que comience su proceso (algunos de ellos). las manipulaciones posibles son bastante inteligentes).
Un ejemplo es:
my_prog <inputfile 2>errorfile | grep XYZ
que lo hará:
- crear un proceso para
my_prog
. - abrir
inputfile
como su entrada estándar (identificador de archivo 0). - abrir
errorfile
como su error estándar (identificador de archivo 2). - crear otro proceso para
grep
. - adjunte la salida estándar de
my_prog
a la entrada estándar degrep
.
Re tu comentario:
Cuando abro estos archivos en la carpeta /dev, ¿por qué nunca puedo ver el resultado de un proceso en ejecución?
Es porque no son archivos normales. Aunque UNIX presenta todo como un archivo en algún sistema de archivos, eso no significa que sea así en los niveles más bajos. La mayoría de los archivos en la /dev
jerarquía son dispositivos de caracteres o de bloques, es decir, un controlador de dispositivo. No tienen tamaño pero si número de dispositivo mayor y menor.
Cuando los abre, está conectado al controlador del dispositivo en lugar de a un archivo físico, y el controlador del dispositivo es lo suficientemente inteligente como para saber que los procesos separados deben manejarse por separado.
Lo mismo ocurre con el /proc
sistema de archivos Linux. Esos no son archivos reales, sólo puertas de enlace estrictamente controladas a la información del kernel.
Sería más correcto decir que stdin
, stdout
y stderr
son "flujos de E/S" en lugar de archivos. Como habrás notado, estas entidades no viven en el sistema de archivos. Pero la filosofía de Unix, en lo que respecta a E/S, es "todo es un archivo". En la práctica, eso realmente significa que puede usar las mismas funciones e interfaces de la biblioteca ( printf
,
scanf
, read
, write
, select
, etc.) sin preocuparse de si el flujo de E/S está conectado a un teclado, un archivo de disco, un socket, una tubería, o alguna otra abstracción de E/S.
La mayoría de los programas necesitan leer entradas, escribir salidas y registrar errores, por lo que stdin
, stdout
y stderr
están predefinidos para usted, para su comodidad de programación. Esto es sólo una convención y el sistema operativo no lo aplica.
Como complemento a las respuestas anteriores, aquí hay un resumen sobre las redirecciones:
EDITAR: Este gráfico no es del todo correcto.
El primer ejemplo no utiliza stdin en absoluto, pasa "hola" como argumento al comando echo.
El gráfico también dice 2>&1 tiene el mismo efecto que &> sin embargo
ls Documents ABC > dirlist 2>&1
#does not give the same output as
ls Documents ABC > dirlist &>
Esto se debe a que &> requiere un archivo al que redirigir, y 2>&1 simplemente envía stderr a stdout