Por que o bash se vincula a ncurses?

11

Eu acho que já notei isso antes, mas nunca pensei muito sobre isso; 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)

O Libtinfo faz parte das ncurses. Este é um sistema fedora, mas é o mesmo no Ubuntu, e eu notei no raspbian (uma variante do Debian) que ele também se liga ao próprio libncurses.

Qual é o motivo disso? Eu pensei que tudo o que o bash fez poderia ser feito com o libreadline (que, curiosamente, não tem link). Isso é simplesmente um substituto para isso?

    
por goldilocks 16.09.2015 / 20:36

2 respostas

17

Se você executar bash como:

LD_DEBUG=bindings bash

em um sistema GNU e grep para bash.*tinfo nessa 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 de nm -D /bin/bash que bash está usando esses símbolos de tinfo.

Trazer a man page 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, bash , mais provavelmente seu editor readline (libreadline está estaticamente ligado), usa aqueles para consultar o banco de dados terminfo para descobrir sobre os recursos do terminal para que ele possa executar seu editor de linhas corretamente (enviando o escape correto seqüências e identificar teclas pressionadas corretamente) em qualquer terminal.

Quanto ao motivo pelo qual a linha de leitura está vinculada estaticamente em bash , você deve ter em mente que readline foi desenvolvido junto com bash pela mesma pessoa e está incluído na origem de bash .

É possível criar bash para ser vinculado ao libreadline instalado pelo sistema, mas somente se ele for de uma versão compatível e não for o padrão. Você precisa chamar o script configure no tempo de compilação com --with-installed-readline .

    
por 16.09.2015 / 21:18
2

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

A página de manual para tgetent (chamada curs_termcap porque é assim que foi feito no SVr4 ...) diz:

These routines are included as a conversion aid for programs that use the termcap library. Their parameters are the same and the routines are emulated using the terminfo database. Thus, they can only be used to query the capabilities of entries for which a terminfo entry has been compiled.

Ou seja, se o programa de chamada não olhar de perto para 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 (xterm é uma exceção rara - veja as perguntas frequentes ). Então bash trabalha com ncurses.

No entanto, a biblioteca termcap é menor que ncurses. Muito tempo atrás, isso importava, e desde 1997 ncurses teve uma opção de configuração --with-termlib , o que o torna construa as partes específicas de termcap e terminfo como uma biblioteca separada das funções necessárias na biblioteca de curses de nível superior. Alguns anos se passaram e algumas das distribuições baseadas em Linux incorporaram isso em seus pacotes.

Como bash não usa nenhuma das funções curses (libncurses, etc.), é razoável vincular somente o libtinfo .

readline é a parte específica de termcap de bash (na verdade, quando encontrei pela primeira vez bash , suas partes termcap foram codificadas , mesmo que o oficial fonte usada termcap - talvez para salvar mais alguns bytes). Quando bash é criado com o pacote readline , você não verá readline como uma biblioteca separada, porque não faria sentido colocar a readline instalada como uma biblioteca compartilhada (possivelmente conflitante). Mas (dependendo do seu sistema), você pode ver libtinfo porque ncurses é construído de uma forma ou de outra (dividida ou não) - não ambos.

    
por 12.07.2016 / 22:47