Por que o bash está vinculado a ncurses?

11

Acho que já notei isso antes, mas nunca pensei muito; agora estou 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 é parte de ncurses. Este é um sistema fedora, mas é o mesmo no ubuntu, e noto no raspbian (uma variante debian) que também se vincula ao libncurses.

Qual o motivo disso? Eu pensei que tudo o que o bash fazia poderia ser feito com libreadline (que, curiosamente, não está vinculado a). Isso é simplesmente um substituto para isso?

Cachinhos Dourados
fonte
Faz parte das maldições? A descrição do pacote ( biblioteca terminfo de baixo nível compartilhada para manipulação de terminal ) não diz nada ( packages.ubuntu.com/trusty/libtinfo5 ), e parece razoável que um shell o tenha. Talvez seja necessário para valores de TERM? Ah, não importa - eu vejo o pacote fonte ncurses.
muru
zshtambém link para libtinfo também
cuonglm

Respostas:

17

Se você executar bashcomo:

LD_DEBUG=bindings bash

em um sistema GNU, e grep for bash.*tinfonessa saída, você 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'

Você pode confirmar a partir da saída nm -D /bin/bashque bashestá usando esses símbolos do tinfo.

Trazer a página de manual para qualquer um desses símbolos esclarece para que servem:

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

Basicamente, o bashmais provável é que o seu readlineeditor (a libreadline esteja estaticamente vinculada), use-os para consultar o banco de dados terminfo para descobrir sobre os recursos do terminal, para que ele possa executar seu editor de linha corretamente (enviando as seqüências de escape corretas e identificando as teclas pressionadas corretamente) em qualquer terminal.

Quanto ao motivo pelo qual o readline está estaticamente vinculado bash, você deve ter em mente que ele readlineé desenvolvido juntamente bashcom a mesma pessoa e está incluído na fonte de bash.

É possível construir bashpara ser vinculado ao sistema instalado libreadline, mas apenas se esse for de uma versão compatível e esse não for o padrão. Você precisa chamar o configurescript no momento da compilação com --with-installed-readline.

Stéphane Chazelas
fonte
2

bashé um aplicativo termcap via readline, like screene alguns outros programas. Na maioria dos sistemas baseados em Linux (além do Slackware), é provável que você veja ncurses como implementação subjacente do termcap .

A página de manual paratgetent (chamada curs_termcap porque foi assim que foi feita no SVr4 ...) diz:

Essas rotinas são incluídas como um auxílio de conversão para programas que usam a biblioteca termcap . Seus parâmetros são os mesmos e as rotinas são emuladas usando o banco de dados terminfo . Portanto, eles podem ser usados ​​apenas para consultar os recursos das entradas para as quais uma entrada terminfo foi compilada.

Ou seja, se o programa de chamada não observar atentamente os dados retornados e usar a interface termcap convencional para ler a descrição do terminal e gravar dados na tela, ele funcionará exatamente como o termcap original.

A maioria dos aplicativos termcap não parece tão de perto (o xterm é uma exceção rara - consulte as Perguntas frequentes ). Então bashfunciona com ncurses.

No entanto, a biblioteca termcap é menor que ncurses. Há algum tempo, isso importava, e desde 1997 o ncurses possui uma opção de configuração --with-termlibque o constrói partes específicas do termocap e terminfo como uma biblioteca separada das funções necessárias na biblioteca de maldições de nível superior. Alguns anos se passaram e algumas das distribuições baseadas em Linux incorporaram isso em seus pacotes.

Como bashnão usa nenhuma das funções de maldição (libncurses, etc.), é razoável vincular apenas o arquivo libtinfo.

readlineé a parte específica do termcap bash(na verdade, quando eu encontrei pela primeira vez bash, suas partes do termcap foram codificadas permanentemente , mesmo que a fonte oficial usasse o termcap - talvez para economizar mais alguns bytes). Quando bashé construído com o pacote configurável readline, você não verá readlinecomo uma biblioteca separada porque não faria sentido readlineinstalar essa instalação configurada como uma biblioteca compartilhada (possivelmente conflitante). Mas (dependendo do seu sistema), você pode ver libtinfoporque o ncurses é construído de uma maneira ou de outra (dividida ou não) - não as duas.

Thomas Dickey
fonte