为什么 bash 链接到 ncurses?

为什么 bash 链接到 ncurses?

我想我以前就注意到了这一点,但从未认真思考过;现在我很好奇。

> 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 是以一种方式或另一种方式(拆分或不拆分)构建的,而不是两者兼而有之。

相关内容