¿Cómo (y por qué) usar stderr para leer y escribir?

12

Según esta respuesta de schily , lesslee los comandos de navegación de stderr si no puede abrirse /dev/tty.

Esto parece desconcertante, ya que nunca he visto nada escribir en la secuencia stderr de otro programa, y ​​no sé cómo podría lograrlo.

¿Cuál es el propósito de que stderr esté abierto tanto para leer como para escribir? Y si esto es útil, ¿cómo lo uso en los sistemas modernos? (¿Existe alguna sintaxis arcana para canalizar algo en stderr en lugar de stdin, por ejemplo?)

Draconis
fuente

Respuestas:

7

Me sorprendió al principio. Sin embargo, después de leer las respuestas e investigar un poco, parece simple. Así que aquí está lo que he encontrado. (Al final no hubo sorpresa).

Antes de la redirección, stdin, stdout y stderr están conectados según lo esperado al mismo dispositivo.

#ctrl-alt-delor:~$
#↳ ll /dev/std*
lrwxrwxrwx 1 root root 15 Jun  3 20:58 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Jun  3 20:58 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root 15 Jun  3 20:58 /dev/stdout -> /proc/self/fd/1

#ctrl-alt-delor:~$
#↳ ll /proc/self/fd/*
lrwx------ 1 richard richard 64 Jun 30 19:14 /proc/self/fd/0 -> /dev/pts/12
lrwx------ 1 richard richard 64 Jun 30 19:14 /proc/self/fd/1 -> /dev/pts/12
lrwx------ 1 richard richard 64 Jun 30 19:14 /proc/self/fd/2 -> /dev/pts/12

Por lo tanto, después de la mayoría de las redirecciones (es decir, si stderr) no se redirige. stderr todavía está conectado a la terminal. Por lo tanto, se puede leer para obtener la entrada del teclado.

Lo único que detiene los archivos que se usan en la dirección inesperada es la convención, y las tuberías son unidireccionales.

Otro ejemplo, prueba:

cat | less

Esto sale mal después de una página, cuando lessintenta leer el terminal (esto no es una sorpresa, ya catque también está leyendo el terminal).

/dev/ttyEs más misterioso, no es un enlace /proc/self.

#ctrl-alt-delor:~$
#↳ ll /dev/tty
crw-rw-rw- 1 root tty 5, 0 Jun 29 09:18 /dev/tty

¿ Ve qué relaciones hay entre mi terminal de control actual y `/ dev / tty`? por una explenation. Gracias a @StephenKitt por el enlace.

ctrl-alt-delor
fuente
Al respecto /dev/tty, vea esta pregunta .
Stephen Kitt
6

Cuando inicia sesión, stdin, stdout y stderr se conectan al terminal desde el que inicia sesión. Para ser más exactos, tty se abre normalmente y stdout y stderr son el resultado de dos dup(2)operaciones en el primer descriptor de archivo. Esto permite leer desde stderr para obtener información del termnal.

Como se menciona en la otra respuesta, los programas leen desde stderr para obtener una respuesta interactiva sobre una pregunta.

Dado que un usuario no puede saber en qué circunstancias un programa lee desde stderr, es un intento inútil escribir intencionalmente datos en stderr desde otro programa.

Tenga en cuenta que hoy en día los programas generalmente intentan abrir /dev/ttyy usar stderr solo en caso de que no funcione.

Los programas que solo leen desde stderr por lo general nunca se han modificado desde antes de 1979 y estos programas generalmente contienen construcciones como:

int i 1;

o

i =* 2;

que no son aceptados por los compiladores modernos de C. Como resultado, es muy poco probable que hoy encuentre un programa que nunca se abra, /dev/ttysino que lea las respuestas interactivas de stderr.

astuto
fuente
Entonces, si entiendo bien, ¿el shell se conecta stderral tty cuando stdinse redirige (a través de una tubería u otro medio)? ¿O simplemente siempre se conecta stderral tty?
Draconis
1
Cuando inicia sesión, stderr está conectado a su terminal de inicio de sesión.
schily
2
i =+ 1es perfectamente válido C y es igual a i = (+1). De acuerdo, el primero es un buen candidato para el concurso de C.
G. Sliepen
1
OK, puede ser que solo crea una advertencia. Cambié el código a otra cosa desde C en 1977.
2018
1
Parece que soy consciente de más conchas, ya que no sé de al menos una cáscara que se lee de que no sea su entrada estándar . (-:
JdeBP 01 de