GNU/Linux >> Tutoriales Linux >  >> Linux

¿Es posible que el descriptor de archivo de Linux 0 1 2 no sea para stdin, stdout y stderr?

En el nivel del descriptor de archivo, stdin se define como descriptor de archivo 0 , salida estándar se define como descriptor de archivo 1; y stderr se define como descriptor de archivo 2 . Mira esto.

Incluso si su programa, o el shell, cambia (por ejemplo, redirigir con dup2 (2)) cuál es el descriptor de archivo 0, siempre permanece stdin (ya que por definición STDIN_FILENO es 0).

Syscalls como open(2) o pipe(2) o socket(2) pueden dar, p. STDIN_FILENO (es decir, 0) si ese descriptor de archivo está libre (por ejemplo, porque ha sido close(2)-d antes). Pero cuando eso ocurre, sigue siendo stdin por definición.

Por supuesto, en stdio(3), el FILE stream stdin es un poco más complejo. Su programa podría fclose(3), freopen(3), fdopen(3) ...


Aunque ya existían un par de respuestas, pero no las encontré lo suficientemente informativas como para explicar la historia completa.

Dado que seguí adelante e investigué más, estoy agregando mis hallazgos.

Cada vez que se inicia un proceso, se agrega una entrada del proceso en ejecución al /proc/<pid> directorio. Este es el lugar donde se guardan todos los datos relacionados con el proceso. Además, al iniciar el proceso, el kernel asigna 3 descriptores de archivo al proceso para la comunicación con los 3 flujos de datos denominados stdin , stdout y stderr .
el kernel de Linux usa un algoritmo para crear siempre un FD con el valor entero más bajo posible, por lo que estos flujos de datos se asignan a los números 0 , 1 y 2 .

Dado que estas no son más que referencias a una transmisión, podemos cerrar una transmisión. Uno puede llamar fácilmente al close(<fd>) , en nuestro caso close(1) , para cerrar el descriptor de archivo.

al hacer ls -l /proc/<pid>/fd/ , solo vemos 2 FD enumerados allí 0 y 2 .
Si ahora hacemos un open() llamar al kernel creará un nuevo FD para mapear esta nueva referencia de archivo y dado que el kernel usa el primer algoritmo de entero más bajo, tomará el valor entero 1 .

Así que ahora, el nuevo FD creado apunta al archivo que abrimos (usando el open() llamada al sistema)
Cualquiera de las transferencias de datos que ocurren ahora no se realiza a través del flujo de datos predeterminado que se vinculó anteriormente, sino del nuevo archivo que abrimos.

Entonces sí, podemos mapear el FD 0 , 1 o 2 a cualquiera de los archivos y no es necesario stdin , stdout o stderr


Linux
  1. ¿Qué tan portátiles son /dev/stdin, /dev/stdout y /dev/stderr?

  2. Cómo auditar modificaciones de archivos y ejecuciones de archivos en Linux

  3. ¿Cómo puede un proceso interceptar stdout y stderr de otro proceso en Linux?

  4. ¿Cómo vaciar (truncar) un archivo en Linux que ya existe y está protegido de alguna manera?

  5. En Linux, ¿es posible cifrar una carpeta/partición de manera que nadie pueda acceder a ella sin la contraseña?

Arreglar Grub que no se muestra para el sistema de arranque dual de Windows y Linux

50 comandos grep productivos y prácticos para entusiastas de Linux

20 mejores programas de cifrado de discos y archivos para escritorio Linux

¿Es posible hacer que las salidas stdout y stderr sean de diferentes colores en XTerm o Konsole?

¿Confundido acerca de stdin, stdout y stderr?

Captura de STDERR y STDOUT para archivar usando tee