La spécification POSIX couvre vraiment ses paris en ce qui concerne le Terminal de Contrôle et qu'elle définit ainsi:
- Terminal de contrôle
- La question de savoir si plusieurs fichiers spéciaux se référant au terminal sont concernés n'est pas traitée dans POSIX.1. Le chemin d'accès
/dev/tty
est synonyme du terminal de contrôle associé à un processus.
C'est dans la liste des définitions - et c'est tout ce qu'il y a. Mais dans General Terminal Interface , on en dit plus:
Un terminal peut appartenir à un processus en tant que terminal de contrôle. Chaque processus d'une session qui a un terminal de contrôle a le même terminal de contrôle. Un terminal peut être le terminal de contrôle pour au plus une session. Le terminal de contrôle d'une session est alloué par le chef de session d'une manière définie par l'implémentation. Si un chef de session n'a pas de terminal de contrôle et ouvre un fichier de périphérique de terminal qui n'est pas déjà associé à une session sans utiliser l'option O_NOCTTY (voir open ()), il est défini par l'implémentation si le terminal devient le terminal de contrôle de la session chef.
Le terminal de contrôle est hérité par un processus enfant lors d'un appel de fonction fork (). Un processus abandonne son terminal de contrôle lorsqu'il crée une nouvelle session avec lesetsid()
une fonction; d'autres processus restant dans l'ancienne session qui avaient ce terminal comme terminal de contrôle continuent de l'avoir. À la fermeture du dernier descripteur de fichier du système (qu'il se trouve ou non dans la session en cours) associé au terminal de contrôle, il n'est pas spécifié si tous les processus qui avaient ce terminal comme terminal de contrôle cessent d'avoir un terminal de contrôle. Il n'est pas précisé si et comment un chef de session peut réacquérir un terminal de contrôle après que le terminal de contrôle a été abandonné de cette manière. Un processus ne renonce pas à son terminal de contrôle simplement en fermant tous ses descripteurs de fichiers associés au terminal de contrôle si d'autres processus continuent de l'ouvrir.
Il reste beaucoup de choses non spécifiées - et honnêtement, je pense que cela a du sens. Bien que le terminal soit une interface utilisateur clé, il y a aussi toutes sortes d'autres choses dans certains cas - comme le matériel réel, ou même une sorte d'imprimante - mais dans beaucoup de cas, ce n'est pratiquement rien du tout - comme un xterm
qui n'est qu'un émulateur . Il est difficile d'être précis là-bas - et je ne pense pas que ce serait dans l'intérêt de Unix de toute façon, car les terminaux font beaucoup plus que Unix.
Quoi qu'il en soit, POSIX est également assez sceptique sur la façon de ps
se comporter en ce qui concerne le ctty.
Il y a l' -a
interrupteur:
- Écrivez des informations pour tous les processus associés aux terminaux. Les implémentations peuvent omettre les chefs de session de cette liste.
Génial. Les chefs de session peuvent être omis. Ce n'est pas très utile.
Et -t
:
- Écrivez les informations pour les processus associés aux terminaux donnés dans la liste de termes. La demande doit garantir que la liste terminologique est un argument unique sous la forme d'une
<blank>
liste séparée par des virgules. Les identifiants de terminal doivent être donnés dans un format défini par l'implémentation .
... ce qui est une autre déception. Mais cela continue à dire à propos des systèmes XSI:
- Sur les systèmes conformes à XSI, ils doivent être donnés sous l'une des deux formes suivantes: le nom de fichier de l'appareil (par exemple,
tty04
) ou, si le nom de fichier de l'appareil commence par tty
, juste l'identifiant suivant les caractères tty
(par exemple, 04
) .
C'est un peu mieux, mais ce n'est pas un chemin. Sur les systèmes XSI, il y a également le -d
commutateur:
- Écrivez des informations pour tous les processus, à l'exception des chefs de session.
... ce qui est au moins clair. Vous pouvez également spécifier le -o
commutateur de sortie avec la tty
chaîne de format, mais, comme vous l'avez noté, son format de sortie est défini par l'implémentation. Pourtant, je pense que c'est aussi bon que possible. Je pense que - avec beaucoup de travail - les commutateurs ci-dessus en combinaison avec d'autres utilitaires peuvent vous donner une assez bonne idée. Pour être tout à fait honnête, je ne sais pas quand / comment ça se casse pour vous - et je n'ai pas pu imaginer une situation dans laquelle cela se produirait. Mais, je pense que probablement si nous ajoutons fuser
et find
nous pouvons vérifier le chemin.
exec 2<>/dev/null
ctty=$(sh -c 'ps -p "$$" -o tty=' <&2)
sid=$(sh -c 'ps -Ao pid= -o tty=|
grep '"$ctty$"' |
grep -Fv "$(ps -do pid=)"' <&2)
find / -type c -name "*${ctty##*/}*" \
-exec fuser -uv {} \; 2>&1 |
grep ".*$ctty.*${sid%%"$ctty"*}"
Le /dev/null
truc était juste pour montrer que cela pouvait fonctionner quand aucun des sous-coquilles de recherche n'avait de 0,1,2 connecté au ctty. Quoi qu'il en soit, cela imprime:
/dev/pts/3: mikeserv 3342 F.... (mikeserv)zsh
Maintenant, ce qui précède obtient le chemin complet sur ma machine, et j'imagine que ce serait le cas pour la plupart des gens dans la plupart des cas. Je peux aussi imaginer que cela pourrait échouer. C'est juste une heuristique grossière.
Cela pourrait probablement échouer pour de nombreuses autres raisons, mais si vous êtes sur un système qui permet au chef de session de renoncer à tous les descripteurs du ctty et de rester le sid alors comme le permet la spécification, alors cela ne va certainement pas aider. Cela dit, je pense que cela peut obtenir une assez bonne estimation dans la plupart des cas.
Bien sûr, la chose la plus simple à faire si vous avez des descripteurs connectés à votre ctty est juste ...
tty <&2
...ou similaire.
ps
solution couvre la plupart des systèmes (etwho
n'aide pas plusps
), peut-être avec un peu plus de code pour gérer l'identifiant seul (comme "04"). Je me demandais s'il y avait une solution encore plus portable.