Za każdym razem, gdy ktoś ustawia inny rozmiar wirtualnej konsoli, less
rozpoznaje rozdzielczość okna (zakładam, że ...); zgodnie z tym zmienia liczbę wierszy tekstu, które powinien wizualizować. Jak obliczany jest ten parametr?
Za każdym razem, gdy ktoś ustawia inny rozmiar wirtualnej konsoli, less
rozpoznaje rozdzielczość okna (zakładam, że ...); zgodnie z tym zmienia liczbę wierszy tekstu, które powinien wizualizować. Jak obliczany jest ten parametr?
Odpowiedzi:
Jeśli szukasz sposobu na sprawdzenie ze skryptu, możesz wykonać jedną z następujących czynności:
tput cols
i tput lines
, jak sugeruje manatworkAle jeśli chcesz poznać szczegóły, zaczynamy:
W przypadku wirtualnych terminali (xterm, i in.) Istnieje ioctl()
wywołanie systemowe, które powie ci, jaki jest rozmiar okna. Jeśli to możliwe, less
wykorzystuje to połączenie. Ponadto, po zmianie rozmiaru okna, cokolwiek działa w tym oknie, odbiera SIGWINCH
sygnał, który less
informuje, że powinien sprawdzić nowy rozmiar okna. Na przykład rozpocząłem less
uruchamianie (jako identyfikator procesu 16663), połączyłem się z nim strace
i zmieniłem rozmiar okna. Oto co zobaczyłem:
$ 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
Jest to również co tput cols
i tput lines
zrobić za kulisami, jeśli to możliwe. Aby uzyskać więcej informacji na temat tej metody, zobacz man tty-ioctl
i wyszukaj TIOCGWINSZ.
Jednak w przypadku innych terminali, takich jak te podłączone do portów szeregowych, nie ma możliwości bezpośredniego uzyskania tych informacji. W takim przypadku less
zaczyna szukać wskazówek w zmiennych środowiskowych.
LINES
i COLUMNS
często będą ustawione na wymiary terminala. W rzeczywistości, jeśli bash
lub zsh
może znaleźć wymiary terminala, automatycznie ustawi te zmienne, aby ułatwić niezbyt sprytnym programom sprawdzenie rozmiaru terminala. Jednak większość innych powłok, w tym dash
i tcsh
, nie ustawia tych zmiennych.TERM
jest zwykle ustawiony na typ terminala, w którym to przypadku baza danych terminfo może zawierać oczekiwany rozmiar terminala. Jeśli tput rows
nie możesz użyć IOCTL (na przykład, jeśli jesteś podłączony przez port szeregowy), wróci do wartości tutaj zarejestrowanych. W przypadku terminala, którego rozmiar może się zmienić, jest to tylko przypuszczenie i prawdopodobnie będzie błędne.Aby uzyskać więcej informacji, zobacz man tput
komendę sterującą terminalem oraz man terminfo
listę rzeczy, które możesz powiedzieć terminalowi, aby zrobił.
Jeśli spojrzysz na kod źródłowy, poznasz less
wywołania w ioctl()
celu pobrania rozmiaru okna w systemie Linux.
#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
Nie jestem pewien, czy jest to informacja, której szukasz. Chyba less
rejestruje moduł obsługi sygnału SIGWINCH
. Kiedy zmienia się wymiar terminala, otrzymuje SIGWINCH
sygnał i sprawdza informacje tty dla bieżącego wymiaru terminala.
http://www.gnu.org/software/libc/manual/html_node/Miscellaneous-Signals.html