less はどのようにして端末の解像度を知るのでしょうか?

less はどのようにして端末の解像度を知るのでしょうか?

誰かが仮想コンソールに異なるサイズを設定するたびに、lessウィンドウの解像度が認識されます (... と想定しています)。それに応じて、視覚化するテキストの行数が変更されます。そのパラメーターはどのように計算されるのでしょうか?

答え1

スクリプトから確認する方法を探している場合は、次のいずれかを実行できます。

  • 実行しtput colstput lines、manatworkが示唆するように
  • $LINESと$COLUMNSの値を確認する

しかし、詳細を知りたい場合は、次のようになります。

仮想端末 (xterm など) には、ioctl()ウィンドウのサイズを知らせるシステム コールがあります。可能であれば、lessはこのコールを使用します。さらに、ウィンドウのサイズを変更すると、そのウィンドウで実行されているものはすべて、新しいウィンドウ サイズを確認する必要があることを知らせるSIGWINCHシグナルを受け取りますless。たとえば、lessの実行を開始し (プロセス ID 16663 として)、 で接続しstrace、ウィンドウのサイズを変更しました。次の画面が表示されました。

$ strace -p 16663
Process 16663 attached - interrupt to quit
read(3, 0xbfb1f10f, 1)                  = ? ERESTARTSYS (To be restarted)
--- SIGWINCH (Window changed) @ 0 (0) ---
rt_sigaction(SIGWINCH, {0x805cf10, [WINCH], SA_RESTART}, {0x805cf10, [WINCH], SA_RESTART}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig -icanon -echo ...}) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig -icanon -echo ...}) = 0
ioctl(1, TIOCGWINSZ, {ws_row=40, ws_col=80, ws_xpixel=0, ws_ypixel=0}) = 0
ioctl(2, TIOCGWINSZ, {ws_row=40, ws_col=80, ws_xpixel=0, ws_ypixel=0}) = 0

これは、可能であれば、舞台裏で実行される処理でもあります。この方法の詳細については、TIOCGWINSZ を参照してtput cols検索してください。tput linesman tty-ioctl

ただし、シリアル ポートに接続されている端末など、他の端末の場合は、この情報を直接取得する方法はありません。その場合は、less環境変数で手がかりを探し始めます。

  • LINESおよび は、COLUMNS多くの場合、端末のサイズに設定されます。実際、bashまたは がzsh端末のサイズを見つけることができれば、これらの変数を自動的に設定し、それほど賢くないプログラムでも端末のサイズを簡単に確認できるようにします。ただし、dashや を含む他のほとんどのシェルはtcsh、これらの変数を設定しません。
  • TERM通常は端末タイプに設定され、その場合、terminfo データベースには端末の予想されるサイズが含まれている可能性があります。IOCTL をtput rows使用できない場合 (たとえば、シリアル ポート経由で接続している場合)、ここに記録された値にフォールバックします。サイズが変化する可能性のある端末の場合、これは推測にすぎず、間違っている可能性があります。

詳細については、man tputターミナルを制御するコマンドについては を、man terminfoターミナルに指示できる操作のリストについては を参照してください。

答え2

ソースコードを見ると、Linux 上でウィンドウ サイズを取得するためのless呼び出しがわかります。ioctl()

#ifdef TIOCGWINSZ
    {
        struct winsize w;
        if (ioctl(2, TIOCGWINSZ, &w) == 0)
        {
            if (w.ws_row > 0)
                sys_height = w.ws_row;
            if (w.ws_col > 0)
                sys_width = w.ws_col;
        }
    }
#else
#ifdef WIOCGETD
    {
        struct uwdata w;
        if (ioctl(2, WIOCGETD, &w) == 0)
        {
            if (w.uw_height > 0)
                sys_height = w.uw_height / w.uw_vs;
            if (w.uw_width > 0)
                sys_width = w.uw_width / w.uw_hs;
        }
    }
#endif

答え3

これがあなたが探している情報かどうかはわかりません。lessのシグナル ハンドラーを登録していると思いますSIGWINCH。端末の寸法が変わると、シグナルが取得されSIGWINCH、端末の現在の寸法の tty 情報が調べられます。 http://www.gnu.org/software/libc/manual/html_node/Miscellaneous-Signals.html

関連情報