¿Por qué bash se vincula a ncurses?

11

Creo que me he dado cuenta de esto antes, pero nunca lo pensé mucho; ahora estoy curioso.

> 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 es parte de ncurses. Este es un sistema fedora, pero es lo mismo en ubuntu, y noto que en raspbian (una variante de debian) también se vincula a libncurses.

¿Cuál es la razón de esto? Pensé que todo lo que hizo bash podría hacerse con libreadline (que curiosamente, no se vincula a). ¿Es esto simplemente un sustituto de eso?

encerrada dorada
fuente
¿Es parte de ncurses? La descripción del paquete ( biblioteca terminfo de bajo nivel compartida para el manejo de terminales ) no dice nada ( packages.ubuntu.com/trusty/libtinfo5 ), y parece razonable que lo tenga un shell. Tal vez necesario para los valores de TERM? Ah, no importa, veo que el paquete fuente es ncurses.
muru
zshtambién enlace a libtinfo, también
cuonglm

Respuestas:

17

Si corres bashcomo:

LD_DEBUG=bindings bash

en un sistema GNU, y grep bash.*tinfoen esa salida, verá algo como:

   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'

Puede confirmar a partir de la salida nm -D /bin/bashque bashestá usando esos símbolos de tinfo.

Al traer la página de manual de cualquiera de esos símbolos se aclara para qué sirven:

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

Básicamente, lo bashmás probable es que su readlineeditor (libreadline está enlazado estáticamente) los use para consultar la base de datos terminfo para conocer las capacidades del terminal para que pueda ejecutar su editor de línea correctamente (enviando las secuencias de escape correctas e identificando las teclas presionadas correctamente) en cualquier terminal.

En cuanto a por qué readline está estáticamente vinculado bash, debe tener en cuenta que readlinese desarrolla junto bashcon la misma persona y se incluye en la fuente de bash.

Es posible construir bashpara vincularlo con el sistema instalado libreadline, pero solo si esa es de una versión compatible, y esa no es la predeterminada. Debe llamar al configurescript en tiempo de compilación con --with-installed-readline.

Stéphane Chazelas
fuente
2

bashes una aplicación de termcap a través de readline, como screeny algunos otros programas. En la mayoría de los sistemas basados ​​en Linux (aparte de Slackware), es probable que vea ncurses como la implementación subyacente de termcap .

La página del manual paratgetent (llamado curs_termcap porque así se hizo en SVr4 ...) dice:

Estas rutinas se incluyen como una ayuda de conversión para programas que usan la biblioteca termcap . Sus parámetros son los mismos y las rutinas se emulan utilizando la base de datos terminfo . Por lo tanto, solo se pueden usar para consultar las capacidades de las entradas para las que se ha compilado una entrada terminfo .

Es decir, si el programa que realiza la llamada no examina de cerca los datos devueltos y utiliza la interfaz de termcap convencional para leer la descripción del terminal y escribir datos en la pantalla, funciona igual que el termcap original.

La mayoría de las aplicaciones de termcap no se ven tan de cerca (xterm es una excepción rara; consulte las preguntas frecuentes ) Entonces bashfunciona con ncurses.

Sin embargo, la biblioteca termcap es más pequeña que ncurses. Hace bastante tiempo, eso importaba, y desde 1997 ncurses ha tenido una opción de configuración --with-termlibque lo hace construir las partes específicas de termincap y terminfo como una biblioteca separada de las funciones necesarias en la biblioteca de curses de nivel superior. Pasaron algunos años y algunas de las distribuciones basadas en Linux lo incorporaron a sus paquetes.

Como bashno usa ninguna de las funciones de maldiciones (libncurses, etc.), es razonable vincular solo contra el libtinfo.

readlinees la parte específica de termcap de bash(en realidad, cuando me encontré por primera vez bash, sus partes de termcap estaban codificadas , a pesar de que la fuente oficial usó termcap, tal vez para ahorrar unos pocos bytes más). Cuando bashse compila con el paquete readline, no lo verá readlinecomo una biblioteca separada porque no tendría sentido hacer que la readlineinstalación empaquetada sea ​​una biblioteca compartida (posiblemente conflictiva). Pero (dependiendo de su sistema), es posible que vea libtinfoporque ncurses se construye de una forma u otra (dividida o no), no ambas.

Thomas Dickey
fuente