每次有人為虛擬控制台設定不同的大小時,less
都會識別視窗解析度(我假設...);據此,它會改變它應該可視化的文字行數。該參數是如何計算的?
答案1
如果您正在尋找一種從腳本進行檢查的方法,您可以執行以下任一操作:
- 按照 manatwork 的建議運行
tput cols
和tput 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
通常會被設定為終端尺寸。事實上,如果bash
或zsh
可以找到終端尺寸,它會自動設定這些變數本身,以使不太聰明的程式很容易看到終端尺寸。但是,大多數其他 shell(包括dash
和tcsh
)不設定這些變數。TERM
通常設定為終端類型,在這種情況下,terminfo 資料庫可能包含終端的預期大小。如果tput rows
無法使用 IOCTL(例如,如果您透過序列埠連接),它將回退到此處記錄的值。對於尺寸可以改變的終端,這只是一種猜測,很可能是錯誤的。
有關更多信息,請參閱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