Pourquoi bash est-il lié à ncurses?

11

Je pense que j'ai déjà remarqué cela mais je n'y ai jamais beaucoup pensé; maintenant je suis curieux.

> ldd /bin/bash
        linux-vdso.so.1 =>  (0x00007fff2f781000)
        libtinfo.so.5 => /lib64/libtinfo.so.5 (0x00007f0fdd9a9000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007f0fdd7a5000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f0fdd3e6000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f0fddbf6000)

Libtinfo fait partie de ncurses. C'est un système fedora, mais c'est la même chose sur ubuntu, et je remarque sur raspbian (une variante debian) qu'il est également lié à libncurses lui-même.

Quelle en est la raison? Je pensais que tout ce que bash pouvait faire pouvait être fait avec libreadline (auquel, curieusement, il ne fait pas de lien). Est-ce simplement un substitut à cela?

boucle d'or
la source
Cela fait partie des ncurses? La description du package ( bibliothèque terminfo partagée de bas niveau pour la gestion des terminaux ) ne dit rien ( packages.ubuntu.com/trusty/libtinfo5 ), et cela semble raisonnable pour un shell. Peut-être nécessaire pour les valeurs de TERM? Ah, tant pis - je vois que le paquet source est ncurses.
muru
zshégalement un lien vers libtinfo
cuonglm

Réponses:

17

Si vous vous exécutez en bashtant que:

LD_DEBUG=bindings bash

sur un système GNU, et grep pour bash.*tinfodans cette sortie, vous verrez quelque chose comme:

   797:     binding file bash [0] to /lib/x86_64-linux-gnu/libtinfo.so.5 [0]: normal symbol `UP'
   797:     binding file bash [0] to /lib/x86_64-linux-gnu/libtinfo.so.5 [0]: normal symbol `PC'
   797:     binding file bash [0] to /lib/x86_64-linux-gnu/libtinfo.so.5 [0]: normal symbol `BC'
   797:     binding file bash [0] to /lib/x86_64-linux-gnu/libtinfo.so.5 [0]: normal symbol `tgetent'
   797:     binding file bash [0] to /lib/x86_64-linux-gnu/libtinfo.so.5 [0]: normal symbol `tgetstr'
   797:     binding file bash [0] to /lib/x86_64-linux-gnu/libtinfo.so.5 [0]: normal symbol `tgetflag'

Vous pouvez confirmer à partir de la sortie de nm -D /bin/bashcela en bashutilisant ces symboles de tinfo.

Apporter la page de manuel pour l'un de ces symboles précise à quoi ils servent:

$ man tgetent
NAME
   PC, UP, BC, ospeed, tgetent, tgetflag, tgetnum, tgetstr, tgoto, tputs -
   direct curses interface to the terminfo capability database

Fondamentalement, bashplus vraisemblablement son readlineéditeur (libreadline est lié statiquement dans), utilise ceux-ci pour interroger la base de données terminfo pour en savoir plus sur les capacités du terminal afin qu'il puisse exécuter correctement son éditeur de ligne (en envoyant les séquences d'échappement appropriées et en identifiant correctement les pressions de touches) sur n'importe quel Terminal.

Quant à savoir pourquoi readline est lié statiquement bash, vous devez garder à l'esprit qu'il readlineest développé aux côtés bashde la même personne et est inclus dans la source de bash.

Il est possible de construire bashpour être lié au système installé libreadline, mais seulement si celui-ci est d'une version compatible, et ce n'est pas la valeur par défaut. Vous devez appeler le configurescript au moment de la compilation avec --with-installed-readline.

Stéphane Chazelas
la source
2

bashest une application termcap via readline, comme screenet certains autres programmes. Sur la plupart des systèmes Linux (à l'exception de Slackware), vous verrez probablement ncurses comme une implémentation sous-jacente de termcap .

La page de manuel detgetent (nommée curs_termcap car c'est ainsi que cela a été fait dans SVr4 ...) dit:

Ces routines sont incluses comme aide à la conversion pour les programmes qui utilisent la bibliothèque termcap . Leurs paramètres sont les mêmes et les routines sont émulées à l'aide de la base de données terminfo . Ainsi, ils ne peuvent être utilisés que pour interroger les capacités des entrées pour lesquelles une entrée terminfo a été compilée.

C'est-à-dire que si le programme appelant ne regarde pas de près les données retournées et utilise l'interface termcap conventionnelle pour lire la description du terminal et écrire des données à l'écran, il fonctionne exactement comme le termcap d'origine.

La plupart des applications termcap ne sont pas aussi proches (xterm est une exception rare - voir FAQ ). bashFonctionne donc avec ncurses.

Cependant, la bibliothèque termcap est plus petite que ncurses. Il y a assez longtemps, cela comptait, et depuis 1997, ncurses dispose d'une option de configuration --with-termlibqui lui permet de créer les parties spécifiques à termcap et terminfo en tant que bibliothèque distincte des fonctions nécessaires dans la bibliothèque curses de niveau supérieur. Quelques années ont passé, et certaines des distributions basées sur Linux l'ont incorporé dans leurs packages.

Comme bashn'utilise aucune des fonctions curses (libncurses, etc.), il est raisonnable de ne lier que contre libtinfo.

readlineest la partie spécifique à termcap bash(en fait lorsque je l'ai rencontré pour la première fois bash, ses parties termcap étaient codées en dur , même si la source officielle a utilisé termcap - peut-être pour économiser quelques octets de plus). Quand bashest construit avec le bundle readline, vous ne le verrez pas readlinecomme une bibliothèque séparée car il ne servirait à rien de faire l' readlineinstallation du bundle comme une bibliothèque partagée (éventuellement conflictuelle). Mais (selon votre système), vous pouvez voir libtinfoque ncurses est construit dans un sens ou dans l'autre (divisé ou non) - pas les deux.

Thomas Dickey
la source