¿Cuál es la vida útil de un descriptor de archivo?

11

Como se describe aquí , las redirecciones se usan open()para escribir en un archivo. Hay un descriptor de archivo interno (?) Creado en el shell, y luego se usa cuando es necesario.

¿Se ha creado el descriptor interno para toda la duración del script o la vida útil del shell? ¿Se destruye después de algún tiempo, una serie de operaciones, etc.?

Me refiero en particular a los descriptores de archivos para los archivos que el shell mismo abre para sus operaciones integradas. ¿Se crea el descriptor y se abre el archivo para cada operación? ¿Cuánto tiempo se guardan? Ejemplo:

#!/bin/bash
>>x echo something
...do many other things not related to the file x
>>x echo something more

¿Se mantiene la primera instancia del descriptor hasta la segunda operación?

¿Qué pasa con el shell que uso en una terminal? A veces mantengo una sesión abierta durante días, tal vez incluso semanas. ¿Sigue conservando los descriptores de todos los archivos que operé con shell incorporado?

Jeff Schaller
fuente

Respuestas:

4

Brevemente: es casi seguro que un shell cierre los descriptores de archivo relacionados con las redirecciones inmediatamente después de que se complete el comando.


Detalles: no se menciona explícitamente el cierre de los archivos abiertos mediante redirecciones en POSIX (por lo que puedo ver). Pero no cerrarlos de inmediato no sería muy útil.

Las reglas para el entorno en el que se inician los comandos no permiten pasar descriptores de archivo adicionales. El shell debería tener cuidado de cerrar cualquier archivo adicional que se guarde al iniciar un comando que no debería tenerlos.

Para las > filenameredirecciones de salida habituales , el archivo en caso de que necesite truncarse al iniciar cada comando, incluso si el descriptor de archivo se guardó. Y cualquier descriptor de archivo guardado apuntaría a un archivo incorrecto si el archivo en cuestión fue renombrado o eliminado mientras tanto.

Por ejemplo, esto no se comportaría correctamente si el fd abierto para el primero echose mantuviera abierto y se usara como está para el segundo:

echo foo >> x; mv x y; echo bar >> x

El modelo habitual de fork + exec utilizado para iniciar programas externos también hace que sea muy fácil cerrar automáticamente los archivos cuando se cierra el comando. El shell solo necesita fork()primero y abrir los archivos necesarios en el proceso secundario, antes de llamar exec()para reemplazar el elemento secundario con el comando real. Cuando se cierra el proceso secundario, todos los archivos abiertos por él se cierran automáticamente.


Enawk , sin embargo, la sintaxis para la redirección de salida es similar a la del shell, pero los archivos abiertos se mantienen abiertos hasta que finaliza el script, a menos que se cierre explícitamente. Esto solo se abrirá foouna vez, y tampoco lo truncará entre las impresiones:

awk 'BEGIN { print "a" > "foo"; print "b" > "foo" }'
ilkkachu
fuente
6

Están cerrados cuando terminan. El shell creará 3 descriptores de archivo 0,1,2 para cada comando que ejecute. Estos son solo números, los números se reutilizan. El shell cerrará los archivos antes de volver a usar los descriptores.

Los descriptores de archivo también se pasan a otros procesos. Y si tiene un proceso en segundo plano, todavía tendrá descriptores de archivo.

El ejemplo utiliza 3>&1, esto significa que el descriptor de archivo 3 hace referencia al archivo al que se refiere actualmente el descriptor 1.

ctrl-alt-delor
fuente