Recién comencé a aprender cómo Everything Is A File TM en Linux, lo que me hizo preguntarme qué pasaría si literalmente leía de / dev / stdout:
$ cat /dev/stdout
^C
$ tail /dev/stdout
^C
(El ^Csoy yo matando el programa después de que se cuelga).
Cuando lo intento vim, aparece el mensaje impensable: "/ dev / stdout" no es un archivo. ¡Jadear!
Entonces, ¿qué ocurre? ¿Por qué recibo mensajes de error o bloqueos cuando intento leer estos "archivos"?

Respuestas:
No está recibiendo "bloqueos" de
cat(1)ytail(1), solo están bloqueando la lectura.cat(1)espera la entrada y la imprime tan pronto como ve una línea completa:Aquí escribí
fooEnterbarEnterCTRL- D.tail(1)espera la entrada y la imprime solo cuando puede detectarEOF:Aquí escribí de nuevo
fooEnterbarEnterCTRL- D.Vim es el único que te da un error. Lo hace porque se ejecuta en
stat(2)contra/dev/stdouty descubre que no tiene elS_IFREGbit establecido./dev/stdoutes un archivo, pero no un archivo normal . De hecho, hay algo de baile en el núcleo para darle una entrada en el sistema de archivos. En Linux:En OpenBSD:
En FreeBSD:
fuente
(Casi) todo es un archivo, pero no todo es un archivo normal . No tiene sentido llamar a un editor de texto en algo que es un archivo especial como un directorio, un socket de red, un puerto serie, etc.
El archivo
/dev/stdoutpuede ser una de varias cosas dependiendo de la variante de Unix:En cualquier caso, abrir
/dev/stdoutarchivos similares crea un nuevo descriptor de archivo que está asociado con el mismo archivo que la aplicación ya tiene abierto en el descriptor de archivo 1. “Salida estándar” significa el descriptor de archivo 1, y es solo una convención que se utilice este descriptor de archivo para salida: al núcleo no le importa.Cuando ejecuta un programa en un terminal, los tres descriptores estándar (0 = entrada estándar, 1 = salida estándar, 2 = error estándar) se abren en el dispositivo terminal. La lectura desde ese dispositivo devuelve caracteres escritos por el usuario, y la escritura en ese dispositivo muestra texto en la ventana del terminal. (No existe una forma estándar, dado un dispositivo terminal, de leer la salida que muestra o inyectarle entradas).
Cuando ejecuta
cat /dev/stdout, eso hace exactamente lo mismo quecat /dev/stdinocat /dev/stderr, porque estos tres descriptores de archivo están conectados al mismo archivo: le dicecatque lea desde el terminal. Eso es lo quecatsin argumento hace también.Si ejecutó
cat /dev/stdout >foo,/dev/stdoutse referiría al archivofoo, ese comando es equivalente acat foo >foo. Dependiendo de lacatimplementación, podría producirse un error (la versión de GNU se queja de que "el archivo de entrada es el archivo de salida"), o podría no hacer nada porque lee del archivofooque está vacío (>foosolo lo truncó). Con una versión decatque no detecta este caso especial, sifoono está vacío, entoncescat /dev/stdout >>fooo el equivalentecat foo >>fooagregaría el contenido del archivo a sí mismo indefinidamente.Cuando ejecuta
vim /dev/stdout, se queja porque no sabe cómo editar un terminal (eso simplemente no tiene sentido).fuente
catytailestá buscando contenido opcional seguido de un final de archivo./dev/stdoutsigue abierta, por lo quecat, ytailsólo seguir buscando.fuente