Entiendo que el descriptor de archivo (o controlador de archivo) es una técnica de IO de archivo en sistemas Linux.
También sé que cada proceso tiene 3 flujos estándar (a saber, stdin, stdout y stderr) que están representados por archivos con descriptores de 0 a 3.
Sin embargo, noto que todos los procesos que examiné lsof -p <pid>
tienen un descriptor de archivo adicional 255
con permiso de lectura.
De esta respuesta , aprendí que esta característica es específica del shell Bash , sin embargo, tanto la respuesta como la fuente a la que se hace referencia realmente no explican para qué sirve este descriptor de archivo.
Mi pregunta:
- ¿Para qué sirve el descriptor de archivo 255?
- ¿Puedo usarlo en mi script Bash o es solo un mecanismo de trabajo interno que no debe usarse / manipularse manualmente?
bash
file-descriptors
Tran Triet
fuente
fuente
Respuestas:
Para la última parte de tu pregunta:
¿Puedo usarlo?
De
man bash
:Entonces, si te refieres a usar como crear un nuevo fd con ese número, la respuesta es no.
Si te refieres a usar como: "escribe a esa fd":
O para leerlo:
la respuesta es sí.
Pero, probablemente, debería ser mejor (independiente del shell) usar
/dev/tty
para acceder atty
.¿para qué sirve el descriptor de archivo 255?
Como una conexión alternativa al tty en caso de que fd 1 (
/dev/stdout
) y fd 0 (/dev/stdin
) se bloqueen.Más detalle .
Otros shells pueden usar un número diferente (como 10 en zsh)
De la lista de correo :
fuente
dd bs=1 | bash -i -c 'sleep .1; ls -l /proc/$$/fd' 2>/tmp/err | tee /tmp/out
. Además, ese comentario de la lista de correo trata sobre cuándobash
se ejecuta comobash scriptfile
(255
siendo en ese caso el controlador abierto parascriptfile
, y en ese caso,ls -l /proc/pid/fd
se imprimirá de manera muy convincente255 -> scriptfile
;-)), no sobre cuándo se ejecuta de forma interactiva./dev/tty
, no desde fd 0 o fd 1 c) si fds 0, 1 o 2 se "bloquean", bash no usará ese 255 fd como alternativa para leer la entrada del usuario o para escribir la salida de comandos, instrucciones, mensajes de error, etc.Ese
255
descriptor de archivo es un identificador abierto para el tty de control y solo se usa cuandobash
se ejecuta en modo interactivo.Le permite redirigir
stderr
en el shell principal, al tiempo que permite que el control de trabajo funcione (es decir, poder matar procesos con ^ C, interrumpirlos con ^ Z, etc.).Ejemplo:
Si intenta eso en un shell como
ksh93
, que simplemente usa el descriptor de archivo 2 como referencia al terminal de control, elsleep
proceso se volverá inmune a ^ C y ^ Z, y tendrá que ser eliminado desde otra ventana / sesión. Esto se debe a que el shell no podrá establecer el grupo de procesossleep
como primer plano en el terminaltcsetgrp()
, ya que el descriptor de archivo 2 ya no apunta al terminal.Esto no es
bash
específico, también se usadash
yzsh
, solo que el descriptor no se mueve tan alto (generalmente es 10).zsh
también usará esa fd para hacer eco de las indicaciones y la entrada del usuario, por lo que simplemente funcionará lo siguiente:No tiene nada que ver con los identificadores de archivos que
bash
se utilizan al leer secuencias de comandos y configurar tuberías (que también se duplican con la misma funciónmove_to_high_fd()
), como se sugirió en otras respuestas y comentarios.bash
está utilizando un número tan grande para permitir que los fds sean más grandes que9
para ser utilizados con redireccionamientos en shell (por ejemploexec 87<filename
); eso no es compatible con otros proyectiles.Puede usar ese identificador de archivo usted mismo, pero no tiene mucho sentido hacerlo, porque puede obtener un identificador para el mismo terminal de control en cualquier comando con
... < /dev/tty
.Análisis del código fuente de bash :
En
bash
, el descriptor de archivo del terminal de control se almacena en lashell_tty
variable. Si el shell es interactivo, esa variable se inicializa (al inicio o después de un exec fallido)jobs.c:initialize_job_control()
al duplicarla desdestderr
(sistderr
está conectada a un terminal) o al abrirla directamente/dev/tty
, y luego se duplica nuevamente a un fd más alto congeneral.c:move_to_high_fd()
:Si aún
shell_tty
no es el tty controlador, entonces se hace así:shell_tty
entonces se usa paraobtener y establecer el grupo de procesos en primer plano con
tc[sg]etpgrp
injobs.c:maybe_give_terminal_to()
,jobs.c:set_job_control()
yjobs.c:give_terminal_to()
obtener y establecer los
termios(3)
parámetros enjobs.c:get_tty_state()
yjobs.c:set_tty_state()
obtener el tamaño de la ventana de terminal con
ioctl(TIOCGWINSZ)
inlib/sh/winsize.c:get_new_window_size()
.move_to_high_fd()
generalmente se usa con todos los descriptores de archivos temporales utilizados porbash
(archivos de script, tuberías, etc.), de ahí la confusión en la mayoría de los comentarios que aparecen de manera prominente en las búsquedas de Google.Los descriptores de archivo utilizados internamente por
bash
, incluidos,shell_tty
están configurados en close-on-exec, por lo que no se filtrarán a los comandos.fuente