¿Es seguro utilizar fd 3?

¿Es seguro utilizar fd 3?

Hay varias preguntas que lo utilizan para hacer cosas como múltiples canales de salida sin utilizar la sustitución de procesos:

¿Es seguro utilizar simplemente un número fd fijo para esto? ¿Es posible que un programa ya lo esté usando como se describe?aquí¿Y sobrescribimos algo importante o leemos algo no relacionado?

Respuesta1

¿Es posible que algún programa ya lo esté usando?

No. Verá, la redirección de E/S se produce antes de que se inicie un programa o script.

Normalmente, cuando se inicia un programa o script, solo están abiertos los descriptores estándar (0/entrada estándar, 1/salida estándar y 2/error estándar). (Pueden referirse a una terminal, dispositivo, archivo o incluso un socket de red; pero se espera que estén abiertos. En lugar de "cerrar" uno, redirigimos un descriptor no deseado desde/hacia /dev/null, esencialmente "en ninguna parte"/"nada" .)

Los programas usan descriptores a través de llamadas al sistema, como openlos que usan un descriptor gratuito. Es decir, no le piden al kernel que abra un archivo o socket.a un descriptor específico, el núcleo elige el descriptor. Por lo tanto, el único caso en el que un programa utiliza un descriptor adicional es cuando se espera que ya esté abierto cuando se inicia el programa. Hay algunos demonios de utilidad raros como este: además de los descriptores estándar, esperan que si, por ejemplo, el descriptor 3 está abierto cuando comienzan, esté conectado a su servicio de administración (o algo similar).

Si un programa decide utilizar un descriptor codificado (y la única razón por la que lo haría es porque bifurca y ejecuta otro programa queesperaese descriptor debe estar abierto; como dije, esto es muy raro), el descriptor ya abierto se cierra cuando el programa lo reemplaza con cualquier cosa para la que lo use. (Por cierto, el núcleo realiza el cierre cuando el programa indica que quiere usar un descriptor específico, por ejemplo, dup2()en sistemas POSIXy; el proceso no necesita preocuparse).

Los scripts de Shell (Bash y sh) usan números de descriptores fijos, por lo que es posible que un script use un descriptor específico para realizar algunas redirecciones de entrada/salida. Sin embargo, cuando eso sucede, las redirecciones anteriores simplemente se ignoran y no tienen ningún efecto, porque los scripts suponen que el descriptor estaba cerrado. (Si un descriptor está abierto y el script usa ese descriptor para algunas cosas internas, el descriptor original se cierra primero (por el núcleo y por las razones mencionadas en el párrafo anterior) cuando el script lo redirige. Para cualquier tipo de Para que se produzca una fuga de datos, el script tendría que ser especialmentepruebasi un descriptor ya está abierto, yevitarredireccionándolo.)

También tenga en cuenta que las unidades o canales de E/S de Fortran no están relacionados con descriptores, incluso si ambos usan un número para identificación. Entonces, incluso si un programa Fortran usa la unidad 10, no significa que use el descriptor 10.

¿Es seguro utilizar simplemente un número fd fijo para esto?

Sí. POSIX dice que un programa puede tener al menos 20 descriptores abiertos, por lo que cualquier número fijo entre 3 y 19 debería funcionar bien.

El punto clave es documentarlo bien, preferiblemente en un breve comentario al comienzo del script (para scripts), o en el uso ( -hu --helpopción de línea de comandos) y en la página de manual (para programas).

Para los scripts, puede suponer que si surge un conflicto (y si surge, será del tipo "el script no funciona en absoluto porque la tubería se cierra tan pronto como se inicia el programa", como se detalló anteriormente), los usuarios pueden cambiar el número de descriptor fijo para adaptarse mejor a sus necesidades. Entonces, tu tarea como guionista es planificar con anticipación y hacerlo más fácil para los que vendrán después. (Un comentario claro que describa su intención y el diseño general es suficiente; no es necesario hacer que el número del descriptor sea una variable ni describir cada pequeña acción que realiza el script).

Para los programas, es una buena idea hacerlo configurable en tiempo de ejecución. Por ejemplo, podría hacer que su programa/demonio use el descriptor 3, si está abierto, para un protocolo de control especial con una interfaz gráfica de usuario; pero, usando alguna opción de línea de comandos, como '-c 5', use el descriptor con nombre (o, con -c /dev/nameo use el archivo especificado, canalización con nombre o socket de dominio local). De esta manera, los usuarios pueden solucionar cualquier conflicto con los scripts con facilidad.-c named-pipe-c :socketpath

información relacionada