为什么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上是相同的,我注意到在raspbian(debian变体)上,它也链接到libncurses本身。

这是什么原因呢?我认为bash所做的一切都可以通过libreadline完成(奇怪的是,它没有链接到)。这仅仅是替代吗?


这是ncurses的一部分吗?程序包描述(用于终端处理的共享低级terminfo库)没有任何说明(packages.ubuntu.com/trusty/libtinfo5),对于外壳来说,这听起来很合理。值可能需要TERM?啊,没关系-我看到的是源码包ncurses
muru

zsh也链接到libtinfo
cuonglm

Answers:


17

如果运行bash为:

LD_DEBUG=bindings bash

在GNU系统上,bash.*tinfo在输出中使用grep ,您将看到类似以下内容:

   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/bashbash使用来自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数据库以查找终端功能,以便它可以在任何情况下正确运行其行编辑器(发送正确的转义序列并正确识别按键)终奌站。

至于为什么readline是静态链接到的bash,您必须记住由同一个人readline共同开发bash并包含在bash

可以构建bash与系统的已安装链接libreadline,但前提是该版本具有兼容版本,并且不是默认版本。您需要configure在编译时使用调用脚本--with-installed-readline


2

bash是通过,like 和其他一些程序的termcap应用程序。在大多数基于Linux的系统上(除了Slackware),您可能会将ncurses视为termcap的基础实现。readlinescreen

手动页面tgetent(名为curs_termcap,因为这是它在SVR4所做的那样......)说:

这些例程作为使用termcap库的程序的转换帮助而包括在内。它们的参数相同,并且使用terminfo 数据库模拟例程。因此,它们只能用于查询已为其编译terminfo条目的条目的功能。

也就是说,如果调用程序没有仔细查看返回的数据,而是使用常规的termcap接口读取终端描述并将数据写入屏幕,则其工作原理与原始termcap相同。

大多数termcap应用程序看起来并不那么紧密(xterm是一种罕见的例外,请参阅FAQ)。因此bash适用于ncurses。

但是,termcap库小于ncurses。相当早以前就很重要了,自1997年以来, ncurses有了一个configure选项--with-termlib,它可以将termcap和terminfo的特定部分构建为一个库,与高级curses库中所需的功能分开。几年过去了,一些基于Linux的发行版将其纳入其软件包。

由于bash不使用任何curses函数(libncurses等),因此仅针对进行链接是合理的libtinfo

readline是termcap的特定部分bash(实际上,当我第一次遇到时,即使正式源使用termcap bash,它的termcap部分也是经过硬编码的 -也许可以节省更多字节)。当bash使用捆绑包构建时readline,您将不会看到readline一个单独的库,因为将捆绑包readline安装作为(可能是冲突的)共享库没有意义。但是(取决于您的系统),您可能会看到,libtinfo因为ncurses是以一种或另一种方式(无论是否拆分)构建的-不能同时构建。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.