![为什么 bash 链接到 ncurses?](https://linux22.com/image/73173/%E4%B8%BA%E4%BB%80%E4%B9%88%20bash%20%E9%93%BE%E6%8E%A5%E5%88%B0%20ncurses%EF%BC%9F.png)
我想我以前就注意到了这一点,但从未认真思考过;现在我很好奇。
> 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 完成(奇怪的是,它没有链接到)。这只是它的替代品吗?
答案1
如果您运行bash
为:
LD_DEBUG=bindings bash
在 GNU 系统上,并bash.*tinfo
在该输出中 grep for ,您将看到类似以下内容的内容:
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 数据库以了解终端功能,以便它可以在任何设备上正确运行其行编辑器(发送正确的转义序列并正确识别按键)。终端。
至于为什么 readline 被静态链接到bash
,你必须记住它readline
是由同一个人一起开发的bash
,并且包含在bash
.
可以构建bash
与系统已安装的链接libreadline
,但前提是该版本是兼容版本,并且这不是默认设置。您需要configure
在编译时使用--with-installed-readline
.
答案2
bash
是一个术语帽应用通过readline
、 likescreen
和其他一些程序。在大多数基于 Linux 的系统上(Slackware 除外),您可能会将 ncurses 视为底层实现术语帽。
这手册页tgetent
(命名为curs_termcap因为这就是 SVr4 中的做法...)说:
这些例程作为使用以下命令的程序的转换辅助工具包含在内:术语帽图书馆。它们的参数相同,并且使用以下命令模拟例程术语信息 数据库。因此,它们只能用于查询某个条目的功能。术语信息条目已编译。
也就是说,如果调用程序没有仔细查看返回的数据,而是使用传统的 termcap 接口来读取终端描述并将数据写入屏幕,那么它的工作方式就像原始 termcap 一样。
大多数 termcap 应用程序看起来并没有那么仔细(xterm 是一个罕见的例外 -请参阅常见问题解答)。因此可以bash
与 ncurses 一起使用。
然而,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 是以一种方式或另一种方式(拆分或不拆分)构建的,而不是两者兼而有之。