Почему bash ссылается на ncurses?

11

Я думаю, что заметил это раньше, но никогда не думал об этом; теперь мне любопытно

> 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 является частью ncurses. Это система Fedora, но она одинакова в Ubuntu, и я замечаю, что в Rasbian (вариант Debian) она также связана с самой libncurses.

В чем причина этого? Я думал, что все, что сделал bash, можно сделать с помощью libreadline (что, как ни странно, на него не ссылаются). Это просто замена для этого?

лютик золотистый
источник
Это часть нкурсов? Описание пакета ( совместно используемая низкоуровневая библиотека terminfo для обработки терминала ) ничего не говорит ( packages.ubuntu.com/trusty/libtinfo5 ), и это звучит разумно для оболочки. Может быть нужно для значений TERM? Ах, не берите в голову - я вижу исходный пакет ncurses.
Муру
zshтакже ссылка на libtinfo тоже
cuonglm

Ответы:

17

Если вы запускаете bashкак:

LD_DEBUG=bindings bash

в системе GNU и grep для bash.*tinfoэтого вывода вы увидите что-то вроде:

   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'

Вы можете подтвердить вывод nm -D /bin/bash, bashиспользуя эти символы из tinfo.

Принесение справочной страницы для любого из этих символов проясняет, для чего они:

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

По сути, bashболее вероятно, что его readlineредактор (libreadline статически связан в) использует их для запроса базы данных terminfo, чтобы узнать о возможностях терминала, чтобы он мог правильно запустить свой редактор строк (отправляя правильные escape-последовательности и правильно идентифицируя нажатия клавиш) на любом Терминал.

Что касается того, почему readline статически связан bash, вы должны иметь в виду, что readlineон разработан bashодним и тем же человеком и включен в источник bash.

Сборку bashможно связать с установленной системой libreadline, но только если она имеет совместимую версию, и это не по умолчанию. Вам нужно вызвать configureскрипт во время компиляции с --with-installed-readline.

Стефан Шазелас
источник
2

bashявляется приложением termcap через readline, как screenи некоторые другие программы. В большинстве систем на основе Linux (кроме Slackware) вы, вероятно, увидите ncurses как базовую реализацию termcap .

Страница руководства дляtgetent (названная curs_termcap, потому что так было сделано в SVr4 ...) гласит:

Эти подпрограммы включены в качестве помощи для преобразования программ, которые используют библиотеку termcap . Их параметры одинаковы, и процедуры эмулируются с использованием базы данных terminfo . Таким образом, они могут использоваться только для запроса возможностей записей, для которых была скомпилирована запись terminfo .

То есть, если вызывающая программа не смотрит внимательно на возвращаемые данные и использует обычный интерфейс termcap для чтения описания терминала и записи данных на экран, она работает так же, как и исходный termcap.

Большинство приложений termcap не выглядят так пристально (xterm - редкое исключение - см. FAQ ). Так bashработает с курсами.

Однако библиотека termcap меньше, чем ncurses. Некоторое время назад это имело значение, и с 1997 года ncurses имеет опцию конфигурации, --with-termlibкоторая позволяет создавать части, специфичные для termcap и terminfo, в виде библиотеки, отдельной от функций, необходимых в библиотеке curses более высокого уровня. Прошло несколько лет, и некоторые дистрибутивы на основе Linux включили это в свои пакеты.

Поскольку bashне использует ни одну из функций curses (libncurses и т. Д.), Разумно ссылаться только на libtinfo.

readlineявляется специфичной для termcap частью bash(фактически, когда я впервые столкнулся bash, его части termcap были жестко закодированы , хотя официальный источник использовал termcap - возможно, чтобы сохранить еще несколько байтов). При bashсборке из комплекта readlineвы не увидите readlineотдельную библиотеку, потому что не было бы смысла делать эту комплектную readlineустановку в качестве (возможно, конфликтующей) разделяемой библиотеки. Но (в зависимости от вашей системы) вы можете видеть, libtinfoпотому что ncurses создается так или иначе (разделены или нет), а не оба.

Томас Дики
источник