In che modo meno conosce la risoluzione del terminale?


12

Ogni volta che qualcuno imposta una dimensione diversa per una console virtuale, lessriconosce la risoluzione della finestra (suppongo che ...); in base a ciò, cambia quante righe di testo dovrebbe visualizzare. Come viene calcolato quel parametro?


Uhm ... ok, ma dove posso trovare quella procedura che viene eseguita?
Giuseppe Crinò,

Risposte:


22

Se stai cercando un modo per controllare da uno script, puoi eseguire una di queste due operazioni:

  • Corri tput colse tput lines, come suggerisce la manoscritta
  • controlla i valori di $ LINES e $ COLUMNS

Ma se vuoi i dettagli, eccoci qui:

Per i terminali virtuali (xterm, et al) c'è una ioctl()chiamata di sistema che ti dirà che dimensione ha la finestra. Se possibile, lessusa questa chiamata. Inoltre, quando si modifica la dimensione della finestra, tutto ciò che è in esecuzione in quella finestra riceve un SIGWINCHsegnale che indica lessche dovrebbe verificare la presenza di una nuova dimensione della finestra. Ad esempio, ho avviato una lesscorsa (come processo ID 16663), collegato ad esso con stracee ridimensionato la finestra. Questo è quello che ho visto:

$ 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

Questo è anche cosa tput colse tput linesfare dietro le quinte, se possono. Per ulteriori informazioni su questo metodo, vedere man tty-ioctle cercare TIOCGWINSZ.

Per altri terminali come quelli collegati alle porte seriali, tuttavia, non è possibile ottenere direttamente queste informazioni. In tal caso, lessinizia a cercare indizi nelle variabili di ambiente.

  • LINESe COLUMNSsarà spesso impostato sulle dimensioni del terminale. In effetti, se basho è in zshgrado di trovare le dimensioni del terminale, imposterà automaticamente queste variabili, per facilitare la visualizzazione delle dimensioni del terminale da parte di programmi non così intelligenti. Tuttavia, la maggior parte delle altre shell, incluso dashe tcsh, non imposta queste variabili.
  • TERMdi solito è impostato sul tipo di terminale, nel qual caso il database terminfo può contenere la dimensione prevista del terminale. Se tput rowsnon è possibile utilizzare IOCTL (ad esempio, se si è connessi tramite una porta seriale), si riporterà ai valori registrati qui. Per un terminale le cui dimensioni possono cambiare, questa è solo un'ipotesi ed è probabile che sia sbagliata.

Per maggiori informazioni, vedi man tputper il comando per controllare il terminale e man terminfoper un elenco di cose che puoi dire al terminale di fare.


Il database terminfo non fa ciò che è stato indicato qui. La risposta di @ warl0ck, che contiene meno informazioni, è più accurata.
Thomas Dickey,

@ThomasDickey Hai ragione; tutto ciò che ha sono i valori previsti. Ho corretto la mia risposta; Grazie.
Jander

7

Se dai un'occhiata al codice sorgente, conoscerai le lesschiamate ioctl()per recuperare le dimensioni della finestra su 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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.