Question

Je regarde le code de l'utilitaire 'less', en particulier la façon dont il est saisi au clavier. Fait intéressant, à la ligne 80 de ttyin.c, il définit le descripteur de fichier à lire:

     /*
      * Try /dev/tty.
      * If that doesn't work, use file descriptor 2,
      * which in Unix is usually attached to the screen,
      * but also usually lets you read from the keyboard.
      */
  #if OS2
      /* The __open() system call translates "/dev/tty" to "con". */
      tty = __open("/dev/tty", OPEN_READ);
  #else
      tty = open("/dev/tty", OPEN_READ);
  #endif
      if (tty < 0)
          tty = 2;

Le descripteur de fichier 2 n'est-il pas stderr? Si oui, WTH?! Je pensais que la saisie au clavier était envoyée via stdin.

Fait intéressant, même si vous le faites ls -l * | less, une fois le chargement du fichier terminé, vous pouvez toujours utiliser le clavier pour faire défiler de haut en bas, mais si vous le faites ls -l * | vi, vi vous criera dessus car il ne le fera pas. lu de stdin. Quelle est la grande idée? Comment suis-je arrivé dans ce nouveau pays étrange où stderr est à la fois un moyen de signaler des erreurs à l'écran et de le lire au clavier? Je ne pense plus être au Kansas ...

Était-ce utile?

La solution

$ ls -l /dev/fd/
lrwx------ 1 me me 64 2009-09-17 16:52 0 -> /dev/pts/4
lrwx------ 1 me me 64 2009-09-17 16:52 1 -> /dev/pts/4
lrwx------ 1 me me 64 2009-09-17 16:52 2 -> /dev/pts/4

Une fois connectés à un terminal interactif, les trois descripteurs de fichier standard renvoient à la même chose: votre téléscripteur (ou pseudo-téléscripteur).

$ ls -fl /dev/std{in,out,err}
lrwxrwxrwx 1 root root 4 2009-09-13 01:57 /dev/stdin -> fd/0
lrwxrwxrwx 1 root root 4 2009-09-13 01:57 /dev/stdout -> fd/1
lrwxrwxrwx 1 root root 4 2009-09-13 01:57 /dev/stderr -> fd/2

Par convention, nous lisons à partir de 0 et écrivons dans 1 et 2. Cependant, rien ne nous empêche de faire autrement.

Lorsque votre shell exécute ls -l * | less, il crée un canal entre le descripteur de fichier de ls less et le descripteur de fichier de open("/dev/tty") <=>. De toute évidence, <=> ne peut plus lire l'entrée au clavier de l'utilisateur à partir du descripteur de fichier <=> & # 8211; il essaie de récupérer le téléscripteur comme il le peut.

Si <=> n'a pas été détaché du terminal, <=> lui attribuera le ATS.

Cependant, si cela échoue ... que pouvez-vous faire? <=> tente une dernière fois d'obtenir le TTY, en supposant que le descripteur de fichier <=> est attaché à la même chose que le descripteur de fichier <=>, s'il n'était pas redirigé.

Ceci n'est pas à l'épreuve des échecs:

$ ls -l * | setsid less 2>/dev/null

Ici, <=> reçoit sa propre session (de sorte qu'il ne fait plus partie du groupe de processus actif du terminal, ce qui entraîne l'échec de <=>), et son descripteur de fichier <=> a été modifié & # 8211; maintenant <=> quitte immédiatement, car il émet vers un téléscripteur mais il n'obtient aucune entrée d'utilisateur.

Autres conseils

Eh bien ... tout d'abord, vous semblez manquer l'appel open() qui ouvre "/ dev / tty". Il utilise uniquement le descripteur de fichier 2 si l'appel à open () échoue. Sur un système Linux standard, et probablement sur de nombreux Unices, '/ dev / tty' existe et ne risque pas de provoquer un échec.

Deuxièmement, le commentaire en haut fournit une quantité limitée d'explications quant à la raison pour laquelle ils retombent dans le descripteur de fichier 2. Mon hypothèse est que stdin, stdout et stderr sont assez liés à '/ dev / tty / 'de toute façon, sauf si redirigé. Et puisque les redirections les plus courantes pour stdin et / ou stdout (via la tuyauterie ou < / >), mais moins souvent pour <=>, il y a de fortes chances que l'utilisation de <=> soit toujours connectée au " clavier ".

La même question avec une réponse finale de la personne qui l'a posée se trouve sur linuxquestions bien qu'ils citent une source légèrement différente de less. Et non, je ne comprends pas la majeure partie, je ne peux donc rien faire au-delà de ça:)

Il semble que ce soit une fonctionnalité spécifique à Linux qui envoie une entrée au clavier à FD 2.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top