GNU/Linux >> Tutoriales Linux >  >> Linux

¿Es>&- más eficiente que>/dev/null?

Ayer leí este comentario SO que dice que en el shell (al menos bash ) >&- “tiene el mismo resultado que” >/dev/null .

Ese comentario en realidad se refiere a la guía ABS como la fuente de su información. Pero esa fuente dice que el >&- sintaxis "cierra los descriptores de archivos".

No me queda claro si las dos acciones de cerrar un descriptor de archivo y redirigirlo al dispositivo nulo son totalmente equivalentes. Así que mi pregunta es:¿lo son?

En la superficie, parece que cerrar un descriptor es como cerrar una puerta, ¡pero redirigirlo a un dispositivo nulo es abrir una puerta al limbo! Los dos no me parecen exactamente iguales porque si veo una puerta cerrada, no intentaré tirar nada, pero si veo una puerta abierta asumiré que puedo.

En otras palabras, siempre me he preguntado si >/dev/null significa que cat mybigfile >/dev/null en realidad procesaría cada byte del archivo y lo escribiría en /dev/null que lo olvida. Por otro lado, si el shell encuentra un descriptor de archivo cerrado, tiendo a pensar (pero no estoy seguro) que simplemente no escribirá nada, aunque la pregunta sigue siendo si cat seguirá leyendo cada byte.

Este comentario dice >&- y >/dev/nulldebería “Será lo mismo, pero no es una respuesta tan rotunda para mí. Me gustaría tener una respuesta más autorizada con alguna referencia al estándar o al núcleo fuente o no...

Respuesta aceptada:

No, ciertamente no desea cerrar los descriptores de archivo 0, 1 y 2.

Si lo hace, la primera vez que la aplicación abra un archivo, se convertirá en stdin/stdout/stderr…

Por ejemplo, si lo hace:

echo text | tee file >&-

Cuando tee (al menos algunas implementaciones, como busybox') abre el archivo para escritura, se abrirá en el descriptor de archivo 1 (stdout). Así que tee escribirá text dos veces en file :

$ echo text | strace tee file >&-
[...]
open("file", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 1
read(0, "textn", 8193)                 = 5
write(1, "textn", 5)                   = 5
write(1, "textn", 5)                   = 5
read(0, "", 8193)                       = 0
exit_group(0)                           = ?

Se sabe que eso causa vulnerabilidades de seguridad. Por ejemplo:

chsh 2>&-

Y chsh (una aplicación setuid) puede terminar escribiendo mensajes de error en /etc/passwd .

Algunas herramientas e incluso algunas bibliotecas intentan protegerse contra eso. Por ejemplo GNU tee moverá el descriptor de archivo a uno arriba de 2 si los archivos que abre para escritura están asignados 0, 1, 2 mientras que busybox tee no lo hará.

Relacionado:Linux:¿cuál es el archivo predeterminado para `hostname`?

La mayoría de las herramientas, si no pueden escribir en stdout (porque, por ejemplo, no está abierto), informarán un mensaje de error en stderr (en el idioma del usuario, lo que significa un procesamiento adicional para abrir y analizar archivos de localización...), por lo que ser significativamente menos eficiente y posiblemente hacer que el programa falle.

En cualquier caso, no será más eficiente. El programa seguirá haciendo write() llamada del sistema. Solo puede ser más eficiente si el programa deja de escribir en stdout/stderr después del primer error write() llamada al sistema, pero los programas generalmente no hacen eso. Por lo general, salen con un error o siguen intentándolo.


Linux
  1. Linux:¿Diferencia entre /dev/console, /dev/tty y /dev/tty0?

  2. /dev/sdb:No existe tal archivo o directorio (pero /dev/sdb1, etc. existe)

  3. Linux:diferencia entre /dev/console, /dev/tty y /dev/tty0

  4. kernel:deshabilitar /dev/kmem y /dev/mem

  5. Crear un dispositivo de bloque virtual que escriba en /dev/null

/dev/null en Linux

¿Cuándo debo usar /dev/shm/ y cuándo debo usar /tmp/?

DD de /dev/zero a /dev/null... lo que realmente sucede

Cómo usa Linux /dev/tty y /dev/tty0

hacer eco o imprimir /dev/stdin /dev/stdout /dev/stderr

¿Por qué se requieren < o > para usar /dev/tcp?