Je comprends que le descripteur de fichiers (ou gestionnaire de fichiers) est une technique d'E / S de fichiers dans les systèmes Linux.
Je sais également que chaque processus a 3 flux standard (à savoir stdin, stdout et stderr) qui sont représentés par des fichiers avec des descripteurs de 0 à 3.
Cependant, je remarque que tous les processus que j'ai examinés lsof -p <pid>
ont un descripteur de fichier supplémentaire 255
avec une autorisation de lecture.
De cette réponse , j'ai appris que cette fonctionnalité est spécifique au shell Bash , mais la réponse et la source référencée n'ont pas vraiment expliqué à quoi sert ce descripteur de fichier.
Ma question:
- A quoi sert le descripteur de fichier 255?
- Puis-je en faire usage dans mon script Bash ou s'agit-il simplement d'un mécanisme de travail interne qui n'est pas censé être utilisé / manipulé manuellement?
bash
file-descriptors
Tran Triet
la source
la source
Réponses:
Pour la dernière partie de votre question:
puis-je l'utiliser?
De
man bash
:Donc, si vous entendez utiliser comme création d'un nouveau fd avec ce numéro, la réponse est non.
Si vous voulez dire utiliser comme: "écrire dans ce fd":
Ou pour en lire:
la réponse est oui.
Mais, probablement, il devrait être préférable (indépendamment du shell) d'utiliser
/dev/tty
pour accéder àtty
.à quoi sert le descripteur de fichier 255?
Comme connexion alternative au tty dans le cas où fd 1 (
/dev/stdout
) et fd 0 (/dev/stdin
) se bloquent.Plus de détails .
D'autres shells peuvent utiliser un nombre différent (comme 10 en zsh)
De la liste de diffusion :
la source
dd bs=1 | bash -i -c 'sleep .1; ls -l /proc/$$/fd' 2>/tmp/err | tee /tmp/out
. En outre, ce commentaire de la liste de diffusion concerne le moment oùbash
est exécuté en tant quebash scriptfile
(255
étant dans ce cas le handle ouvert versscriptfile
- et dans ce cas,ls -l /proc/pid/fd
s'imprimera de manière très convaincante255 -> scriptfile
;-)), pas le moment où il est exécuté de manière interactive./dev/tty
, pas depuis fd 0 ou fd 1 c) si fds 0, 1 ou 2 sont "bloqués", bash n'utilisera pas ce 255 fd comme alternative pour lire les entrées de l'utilisateur ou pour écrire la sortie des commandes, les invites, les messages d'erreur, etc.Ce
255
descripteur de fichier est une poignée ouverte pour le tty de contrôle et n'est utilisé que lorsqu'ilbash
est exécuté en mode interactif.Il vous permet de rediriger le
stderr
dans le shell principal, tout en permettant au contrôle de travail de fonctionner (c'est-à-dire de pouvoir tuer les processus avec ^ C, les interrompre avec ^ Z, etc.).Exemple:
Si vous essayez cela dans un shell comme
ksh93
, qui utilise simplement le descripteur de fichier 2 comme référence au terminal de contrôle, lesleep
processus deviendra immunisé contre ^ C et ^ Z, et devra être tué depuis une autre fenêtre / session. En effet, le shell ne pourra pas définir le groupe de processussleep
comme premier plan dans le terminal avectcsetgrp()
, car le descripteur de fichier 2 ne pointe plus vers le terminal.Ce n'est pas
bash
spécifique, il est également utilisé dansdash
etzsh
, seulement que le descripteur n'est pas déplacé aussi haut (il est généralement de 10).zsh
utilisera également ce fd pour faire écho aux invites et aux entrées utilisateur, donc simplement ce qui suit fonctionnera:Cela n'a rien à voir avec les poignées de fichier
bash
utilisées lors de la lecture de scripts et de la configuration de canaux (qui sont également dupés avec la même fonction -move_to_high_fd()
), comme cela a été suggéré dans d'autres réponses et commentaires.bash
utilise un si grand nombre afin de permettre à des fds plus grands que9
d'être utilisés avec des redirections dans le shell (par exempleexec 87<filename
); ce n'est pas pris en charge dans d'autres shells.Vous pouvez utiliser ce handle de fichier vous-même, mais cela ne sert à rien, car vous pouvez obtenir un handle vers le même terminal de contrôle dans n'importe quelle commande avec
... < /dev/tty
.Analyse du code source de bash :
Dans
bash
, le descripteur de fichier du terminal de contrôle est stocké dans lashell_tty
variable. Si le shell est interactif, cette variable est initialisée (au démarrage ou après un exec échoué) en lajobs.c:initialize_job_control()
dupantstderr
(si ellestderr
est attachée à un terminal) ou en l'ouvrant directement/dev/tty
, puis est à nouveau dupée vers un fd supérieur avecgeneral.c:move_to_high_fd()
:Si ce
shell_tty
n'est pas déjà le tty de contrôle, alors il est fait ainsi:shell_tty
est ensuite utilisé pourobtenir et définir le groupe de processus de premier plan avec
tc[sg]etpgrp
injobs.c:maybe_give_terminal_to()
,jobs.c:set_job_control()
etjobs.c:give_terminal_to()
obtenir et définir les
termios(3)
paramètresjobs.c:get_tty_state()
etjobs.c:set_tty_state()
obtenir la taille de la fenêtre du terminal avec
ioctl(TIOCGWINSZ)
inlib/sh/winsize.c:get_new_window_size()
.move_to_high_fd()
est généralement utilisé avec tous les descripteurs de fichiers temporaires utilisés parbash
(fichiers de script, tuyaux, etc.), d'où la confusion dans la plupart des commentaires qui apparaissent en bonne place dans les recherches Google.Les descripteurs de fichiers utilisés en interne par
bash
, notamment,shell_tty
sont tous définis sur close-on-exec, de sorte qu'ils ne seront pas divulgués aux commandes.la source