なぜ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

zshlibtinfoにもリンクします
cuonglm 2015

回答:


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'

tinfoからのシンボルを使用しているnm -D /bin/bashことの出力から確認できますbash

これらのシンボルのmanページを表示すると、その目的が明確になります。

$ 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いることを覚えておく必要readlinebashありbashます。

bashシステムにインストールされているとリンクするようにビルドすることは可能libreadlineですが、それが互換性のあるバージョンであり、それがデフォルトではない場合に限られます。configureコンパイル時にスクリプトをで呼び出す必要があります--with-installed-readline


2

bash、などのいくつかのプログラムを介したtermcapアプリケーションです。ほとんどのLinuxベースのシステム(Slackwareを除く)では、ncursesがtermcapの基本的な実装であると考えられます。readlinescreen

curs_termcapと名付けられたSVr4での方法であるので...)のマニュアルページにtgetentは次のように書かれています:

これらのルーチンは、termcapライブラリを使用するプログラムの変換補助として含まれています。それらのパラメーターは同じであり、ルーチンはterminfo データベースを使用してエミュレートされます。したがって、これらは、terminfoエントリーがコンパイルされたエントリーの機能を照会するためにのみ使用できます。

つまり、呼び出し側プログラムが返されたデータを詳しく調べず、従来のtermcapインターフェイスを使用して端末の説明を読み、画面にデータを書き込む場合、元のtermcapと同じように機能します。

ほとんどのtermcapアプリケーションはそれほど厳密に見えません(xtermはまれな例外です。FAQを参照してください)。だから、bashncursesベースで動作します。

ただし、termcapライブラリはncursesよりも小さいです。かなり前に問題があり、1997年以降、 ncursesには--with-termlib、より高レベルのcursesライブラリで必要な関数とは別のライブラリとして、termcapおよびterminfo固有のパーツを構築する構成オプションがありました。数年が経ち、一部のLinuxベースのディストリビューションはそれをパッケージに組み込んだ。

以来bash呪い機能(libncursesライブラリなど)のいずれかを使用していない、それはに対してのみリンクするのが合理的ですlibtinfo

readlineはtermcap固有の部分ですbash(実際には、私が最初に出会ったとき、公式ソースがtermcapを使用していたとしてもbash、そのtermcapの部分はハードコーディングされていました。おそらく数バイトを節約するためです)。がbundled bashでビルドされている場合、そのバンドルインストールを(競合する可能性がある)共有ライブラリとして作成しても意味がないため、個別のライブラリとしてreadline表示さreadlineれませんreadline。しかし、(システムによっては)libtinfoncursesが(分割されているかどうかに関係なく)どちらか一方の方法で構築されているために表示される場合があります。両方ではありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.