Woher weiß weniger die Terminalauflösung?

11

Jedes Mal, wenn jemand eine andere Größe für eine virtuelle Konsole festlegt, lesserkennt er die Fensterauflösung (ich gehe davon aus, dass ...); dementsprechend ändert es, wie viele Textzeilen es visualisieren soll. Wie wird dieser Parameter berechnet?

Giuseppe Crinò
quelle
Ähm ... ok, aber wo finde ich die ausgeführte Prozedur?
Giuseppe Crinò

Antworten:

21

Wenn Sie nach einer Möglichkeit suchen, anhand eines Skripts zu überprüfen, können Sie eine der folgenden Aktionen ausführen:

  • Laufen Sie tput colsund tput lines, wie Manatwork vorschlägt
  • Überprüfen Sie die Werte von $ LINES und $ COLUMNS

Aber wenn Sie die Details wollen, gehen wir:

Für virtuelle Terminals (xterm et al.) Gibt es einen ioctl()Systemaufruf, der angibt, wie groß das Fenster ist. Wenn es kann, lessnutzt diesen Anruf. Wenn Sie die Größe des Fensters ändern, erhält alles, was in diesem Fenster ausgeführt wird, ein SIGWINCHSignal, das Sie darüber lessinformiert, dass nach einer neuen Fenstergröße gesucht werden soll. Zum Beispiel habe ich eine lessAusführung gestartet (als Prozess-ID 16663), eine Verbindung damit hergestellt straceund die Fenstergröße geändert . Das habe ich gesehen:

$ 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

Dies ist auch was tput colsund tput lineswas hinter den Kulissen zu tun, wenn sie können. Weitere Informationen zu dieser Methode finden Sie unter man tty-ioctlTIOCGWINSZ.

Für andere Terminals, z. B. solche, die an serielle Schnittstellen angeschlossen sind, gibt es jedoch keine Möglichkeit, diese Informationen direkt abzurufen. In diesem Fall wird lessnach Hinweisen in den Umgebungsvariablen gesucht.

  • LINESund COLUMNSwird häufig auf die Anschlussabmessungen eingestellt. Wenn die Terminalabmessungen gefunden werden bashoder gefunden werden zshkönnen, werden diese Variablen automatisch selbst festgelegt, damit nicht so clevere Programme die Terminalgröße leichter erkennen können. Die meisten anderen Shells, einschließlich dashund tcsh, setzen diese Variablen jedoch nicht.
  • TERMwird normalerweise auf den Terminaltyp gesetzt. In diesem Fall kann die terminfo-Datenbank die erwartete Größe des Terminals enthalten. Wenn tput rowsdie IOCTL nicht verwendet werden kann (z. B. wenn Sie über eine serielle Schnittstelle verbunden sind), wird auf die hier aufgezeichneten Werte zurückgegriffen. Für ein Terminal, dessen Größe sich ändern kann, ist dies nur eine Vermutung und wahrscheinlich falsch.

Weitere Informationen finden Sie unter man tputBefehl zum Steuern des Terminals und man terminfoeine Liste der Aufgaben, die Sie dem Terminal mitteilen können.

Jander
quelle
Die terminfo-Datenbank macht nicht das, was hier angegeben wurde. Die Antwort von @ warl0ck, die weniger Informationen enthält, ist genauer.
Thomas Dickey
@ ThomasDickey Du hast recht; Alles, was es hat, sind erwartete Werte. Meine Antwort wurde korrigiert. Vielen Dank.
Jander
7

Wenn Sie sich den Quellcode ansehen, werden Sie lessAufrufe ioctl()zum Abrufen der Fenstergröße unter Linux kennen.

#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
Gänseblümchen
quelle