less如何知道終端解析度?

less如何知道終端解析度?

每次有人為虛擬控制台設定不同的大小時,less都會識別視窗解析度(我假設...);據此,它會改變它應該可視化的文字行數。該參數是如何計算的?

答案1

如果您正在尋找一種從腳本進行檢查的方法,您可以執行以下任一操作:

  • 按照 manatwork 的建議運行tput colstput lines
  • 檢查 $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

如果可以的話,這也是他們在幕後所做的tput cols事情。tput lines有關此方法的更多信息,請參閱man tty-ioctl並蒐索 TIOCGWINSZ。

但是,對於其他終端(例如連接到序列埠的終端),無法直接取得此資訊。在這種情況下,less開始在環境變數中尋找線索。

  • LINES並且COLUMNS通常會被設定為終端尺寸。事實上,如果bashzsh可以找到終端尺寸,它會自動設定這些變數本身,以使不太聰明的程式很容易看到終端尺寸。但是,大多數其他 shell(包括dashtcsh)不設定這些變數。
  • TERM通常設定為終端類型,在這種情況下,terminfo 資料庫可能包含終端的預期大小。如果tput rows無法使用 IOCTL(例如,如果您透過序列埠連接),它將回退到此處記錄的值。對於尺寸可以改變的終端,這只是一種猜測,很可能是錯誤的。

有關更多信息,請參閱man tput參考資料 控制終端的命令,以及man terminfo您可以告訴終端執行的操作的列表。

答案2

如果您查看原始程式碼,您就會知道在 Linux 上檢索視窗大小的呼叫lessioctl()

#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

相關內容