Estoy bastante confundido con el propósito de estos tres archivos. Si mi interpretación es correcta, stdin
es el archivo en el que un programa escribe en sus peticiones para ejecutar una tarea en el proceso, stdout
es el archivo en el que el núcleo escribe su salida y el proceso solicitante tiene acceso a la información desde, y stderr
es el archivo en en el que se ingresan todas las excepciones. Al abrir estos archivos para verificar si realmente ocurren, ¡no encontré nada que sugiera eso!
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!
Respuestas:
Entrada estándar : este es el identificador de archivo que su proceso lee para obtener información de usted.
Salida estándar : su proceso escribe información normal en este identificador de archivo.
Error estándar : su proceso escribe información de error en este identificador de archivo.
Eso es casi tan tonto como puedo hacerlo :-)
Por supuesto, eso es principalmente por convención. No hay nada que le impida escribir su información de error en la salida estándar si lo desea. Incluso puede cerrar los tres controladores de archivos totalmente y abrir sus propios archivos para E / S.
Cuando comienza su proceso, ya debería tener estos identificadores abiertos y solo puede leerlos o escribirles.
De manera predeterminada, es probable que estén conectados a su dispositivo terminal (p. Ej.
/dev/tty
) , Pero los shells le permitirán configurar conexiones entre estos controladores y archivos y / o dispositivos específicos (o incluso canalizaciones a otros procesos) antes de que comience su proceso (algunos de las manipulaciones posibles son bastante inteligentes).Un ejemplo es:
que lo hará:
my_prog
.inputfile
como entrada estándar (identificador de archivo 0).errorfile
como su error estándar (identificador de archivo 2).grep
.my_prog
a la entrada estándar degrep
.Re tu comentario:
Es porque no son archivos normales. Si bien UNIX presenta todo como un archivo en un sistema de archivos en algún lugar, eso no lo hace en los niveles más bajos. La mayoría de los archivos en la
/dev
jerarquía son dispositivos de caracteres o bloques, efectivamente un controlador de dispositivo. No tienen un tamaño pero tienen un 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 es cierto para el sistema de
/proc
archivos de Linux . Esos no son archivos reales, solo puertas de enlace estrictamente controladas a la información del núcleo.fuente
xyz >xyz.out
escribirá su salida estándar en un archivo físico que otros procesos puedan leer.xyz | grep something
conectaráxyz
stdout agrep
stdin más directamente. Si desea acceso sin restricciones a un proceso que no controla de esa manera, deberá buscar algo parecido/proc
o escribir código para filtrar la salida conectándose de alguna manera al núcleo. Puede haber otras soluciones, pero probablemente todas sean tan peligrosas como las demás :-)/dev/stdin
es un enlace simbólico a/proc/self/fd/0
: el primer descriptor de archivo que el programa que se está ejecutando actualmente ha abierto. Entonces, lo que señala/dev/stdin
cambiará de un programa a otro, porque/proc/self/
siempre apunta al 'programa actualmente en ejecución'. (Cualquiera que sea el programa que esté haciendo laopen
llamada.)/dev/stdin
Y amigos fueron puestos allí para hacer que los scripts de shell setuid sean más seguros, y le permiten pasar el nombre/dev/stdin
de archivo a programas que solo funcionan con archivos, pero que desea controlar de manera más interactiva. (Algún día será un truco útil para que lo sepas. :)Sería más correcto decir eso
stdin
,stdout
ystderr
son "secuencias 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, que realmente significa que se pueden utilizar las mismas funciones de biblioteca e interfaces (printf
,scanf
,read
,write
,select
, etc.) sin tener que preocuparse acerca de si la corriente I / O está conectado a un teclado, un archivo de disco, un enchufe, un tubo, o alguna otra abstracción de E / S.La mayoría de los programas tienen que leer la entrada, la salida de escritura, y los errores de registro, por lo que
stdin
,stdout
ystderr
están predefinidos para usted, para su conveniencia programación. Esto es solo una convención y el sistema operativo no lo aplica.fuente
Como complemento de las respuestas anteriores, aquí hay un resumen sobre las redirecciones:
EDITAR: Este gráfico no es del todo correcto, pero no estoy seguro de por qué ...
Sin embargo, el gráfico dice que 2> & 1 tiene el mismo efecto que &>
fuente
Me temo que tu comprensión es completamente al revés. :)
Piense en "entrada estándar", "salida estándar" y "error estándar" desde la perspectiva del programa , no desde la perspectiva del núcleo.
Cuando un programa necesita imprimir resultados, normalmente se imprime en "salida estándar". Un programa generalmente imprime la salida a la salida estándar
printf
, que imprime SOLAMENTE a la salida estándar.Cuando un programa necesita imprimir información de error (no necesariamente excepciones, se trata de una construcción de lenguaje de programación, impuesta en un nivel mucho más alto), normalmente se imprime en "error estándar". Normalmente lo hace con
fprintf
, que acepta una secuencia de archivos para usar al imprimir. La secuencia de archivos podría ser cualquier archivo abierto para escritura: salida estándar, error estándar o cualquier otro archivo que se haya abierto confopen
ofdopen
."estándar en" se usa cuando el archivo necesita leer la entrada, usando
fread
ofgets
, ogetchar
.Cualquiera de estos archivos se puede redirigir fácilmente desde el shell, así:
O, toda la enchilada:
Hay dos advertencias importantes: Primero, "entrada estándar", "salida estándar" y "error estándar" son solo una convención. Son una convención muy fuerte , pero todo es solo un acuerdo de que es muy bueno poder ejecutar programas como este:
grep echo /etc/services | awk '{print $2;}' | sort
y tener las salidas estándar de cada programa conectadas a la entrada estándar del siguiente programa en la tubería.En segundo lugar, he dado las funciones estándar ISO C para trabajar con secuencias de archivos (
FILE *
objetos): en el nivel del núcleo, son todos los descriptores de archivos (int
referencias a la tabla de archivos) y muchas operaciones de nivel inferior comoread
ywrite
, que no hacer el búfer feliz de las funciones de ISO C. Pensé en hacerlo simple y usar las funciones más fáciles, pero de todos modos pensé que deberías conocer las alternativas. :)fuente
stdin
Lee la entrada a través de la consola (por ejemplo, entrada de teclado). Usado en C con scanf
stdout
Produce salida a la consola. Usado en C con printf
stderr
Produce salida de 'error' a la consola. Usado en C con fprintf
Redireccionamiento
La fuente de stdin se puede redirigir. Por ejemplo, en lugar de provenir de la entrada del teclado, puede provenir de un archivo (
echo < file.txt
) u otro programa (ps | grep <userid>
).Los destinos para stdout, stderr también se pueden redirigir. Por ejemplo, stdout se puede redirigir a un archivo:
ls . > ls-output.txt
en este caso, la salida se escribe en el archivols-output.txt
. Stderr puede ser redirigido con2>
.fuente
Creo que la gente que dice que
stderr
debería usarse solo para mensajes de error es engañosa.También debe usarse para mensajes informativos que están destinados al usuario que ejecuta el comando y no para los posibles consumidores posteriores de los datos (es decir, si ejecuta una tubería de shell que encadena varios comandos, no desea mensajes informativos como "obtener el elemento 30 de 42424 "para aparecer en
stdout
ya que confundirán al consumidor, pero es posible que aún desee que el usuario los vea.Vea esto por razones históricas:
fuente
El uso de ps -aux revela los procesos actuales, todos los cuales se enumeran en / proc / as / proc / (pid) /, al llamar a cat / proc / (pid) / fd / 0 imprime todo lo que se encuentra en la salida estándar de ese proceso creo. Así que tal vez,
/ proc / (pid) / fd / 0 - Archivo de salida estándar
/ proc / (pid) / fd / 1 - Archivo de entrada estándar
/ proc / (pid) / fd / 2 - Archivo de error estándar
por ejemplo
Pero solo funcionó bien para / bin / bash, otros procesos generalmente no tenían nada en 0, pero muchos tenían errores escritos en 2
fuente
Para obtener información autorizada sobre estos archivos, consulte las páginas de manual, ejecute el comando en su terminal.
Pero para una respuesta simple, cada archivo es para:
stdout para una salida
stdin para una entrada de flujo
stderr para imprimir errores o mensajes de registro.
Cada programa de Unix tiene cada una de esas transmisiones.
fuente
stderr no realizará el almacenamiento en búfer de IO Cache, por lo que si nuestra aplicación necesita imprimir información crítica de mensajes (algunos errores, excepciones) para consolar o archivar, úsela donde use stdout para imprimir información de registro general, ya que utiliza el almacenamiento en búfer de IO Cache, existe la posibilidad de que antes de escribir nuestros mensajes a la aplicación de archivo puede cerrarse, dejando un complejo de depuración
fuente
Un archivo con almacenamiento en búfer asociado se denomina flujo y se declara como un puntero a un tipo definido de ARCHIVO. La función fopen () crea ciertos datos descriptivos para una secuencia y devuelve un puntero para designar la secuencia en todas las transacciones posteriores. Normalmente hay tres secuencias abiertas con punteros constantes declarados en el encabezado y asociados con los archivos abiertos estándar. Al inicio del programa, tres flujos están predefinidos y no necesitan abrirse explícitamente: entrada estándar (para leer la entrada convencional), salida estándar (para escribir la salida convencional) y error estándar (para escribir la salida de diagnóstico). Cuando se abre, el flujo de error estándar no está completamente protegido; las secuencias de entrada y salida estándar están completamente almacenadas si y solo si se puede determinar que la secuencia no se refiere a un dispositivo interactivo
https://www.mkssoftware.com/docs/man5/stdio.5.asp
fuente