Menos obtiene la entrada de teclado de stderr?
-
10-07-2019 - |
Pregunta
Me estoy tomando un vistazo al código para la que "menos" de la utilidad, específicamente cómo se obtiene la entrada de teclado.Curiosamente, en la línea 80 de ttyin.c, establece el descriptor de archivo para leer:
/*
* Try /dev/tty.
* If that doesn't work, use file descriptor 2,
* which in Unix is usually attached to the screen,
* but also usually lets you read from the keyboard.
*/
#if OS2
/* The __open() system call translates "/dev/tty" to "con". */
tty = __open("/dev/tty", OPEN_READ);
#else
tty = open("/dev/tty", OPEN_READ);
#endif
if (tty < 0)
tty = 2;
No es el descriptor de fichero 2 stderr?Si es así, WTH?!Pensé que la entrada de teclado fue enviado a través de stdin.
Curiosamente, incluso si usted no ls -l * | less
, después de que el archivo termine de cargar, aún puede utilizar el teclado para desplazarse hacia arriba y hacia abajo, pero si no la ls -l * | vi
, luego vi le grite porque no lee de stdin.¿Cuál es la gran idea?¿Cómo termino en esta nueva y extraña tierra donde stderr es tanto una forma de informe de errores a la pantalla y leer desde el teclado?No creo que estoy en Kansas...
Solución
$ ls -l /dev/fd/ lrwx------ 1 me me 64 2009-09-17 16:52 0 -> /dev/pts/4 lrwx------ 1 me me 64 2009-09-17 16:52 1 -> /dev/pts/4 lrwx------ 1 me me 64 2009-09-17 16:52 2 -> /dev/pts/4
Cuando inicia sesión en una interactivas del terminal, todos los estándar de tres descriptores de ficheros punto a la misma cosa:su TTY (o pseudo-TTY).
$ ls -fl /dev/std{in,out,err} lrwxrwxrwx 1 root root 4 2009-09-13 01:57 /dev/stdin -> fd/0 lrwxrwxrwx 1 root root 4 2009-09-13 01:57 /dev/stdout -> fd/1 lrwxrwxrwx 1 root root 4 2009-09-13 01:57 /dev/stderr -> fd/2
Por convención, se lee de 0
y escribir a 1
y 2
.Sin embargo, nada nos impide hacer lo contrario.
Cuando el shell ejecuta ls -l * | less
, crea una tubería de ls
's descriptor de archivo 1
a less
's descriptor de archivo 0
.Obviamente, less
no puede leer el manual de usuario de entrada de teclado de descriptor de archivo 0
– se intenta conseguir el TTY espalda sin embargo puede.
Si less
no se ha desconectado de la terminal, open("/dev/tty")
le dará el TTY.
Sin embargo, en el caso de que no...¿qué se puede hacer? less
hace un último intento para conseguir la TTY, suponiendo que el archivo descriptor de la 2
se adjunta a la misma cosa que el descriptor de archivo 0
se adjunta, si no fuera redirigido.
Este no es failproof:
$ ls -l * | setsid less 2>/dev/null
Aquí, less
se le da su propia sesión (por lo que ya no es una parte de la terminal de activos de proceso de grupo, causando open("/dev/tty")
a fallar), y su descriptor de archivo 2
ha cambiado – ahora less
sale inmediatamente, porque es la salida a una TTY sin embargo, no tiene ninguna entrada de usuario.
Otros consejos
Bien...en primer lugar, parece que falta el open()
convocatoria que abre "/dev/tty'.Sólo se utiliza el archivo descriptor 2 si la llamada a open() falla.En un sistema Linux estándar, y probablemente muchos sistemas unix, '/dev/tty' existe y es poco probable que cause una falla.
En segundo lugar, el comentario en la parte superior proporciona una cantidad limitada de explicación de por qué se caen de nuevo al descriptor de archivo 2.Mi conjetura es que stdin
, stdout
, y stderr
son bastante conectado a '/dev/tty/' de todos modos, a menos que redirige.Y desde el más común de los casos para la entrada y/ o salida estándar (stdout) (a través de tuberías o <
/ >
), pero con menos frecuencia para stderr
, las probabilidades son que el uso de stderr
sería más probable que todavía pueda conectar con el "teclado".
La misma pregunta con una respuesta en última instancia de la persona que la hizo está en linuxquestions aunque citan fuentes ligeramente diferentes de less
. Y no, no entiendo la mayor parte, así que no puedo ayudar más allá de eso :)
Parece ser una funcionalidad específica de Linux que envía la entrada del teclado a FD 2.