¿Cómo sabe menos la resolución del terminal?

12

Cada vez que alguien establece un tamaño diferente para una consola virtual, lessreconoce la resolución de la ventana (supongo que ...); de acuerdo con eso, cambia cuántas líneas de texto debe visualizar. ¿Cómo se calcula ese parámetro?

Giuseppe Crinò
fuente
Uhm ... ok, ¿pero dónde puedo encontrar ese procedimiento que se ejecuta?
Giuseppe Crinò

Respuestas:

22

Si está buscando una forma de verificar desde un script, puede hacer cualquiera de estos:

  • Corre tput colsy tput lines, como sugiere manatwork
  • verifique los valores de $ LINES y $ COLUMNS

Pero si quieres los detalles, aquí vamos:

Para terminales virtuales (xterm, et al) hay una ioctl()llamada al sistema que le indicará el tamaño de la ventana. Si puede, lessutiliza esta llamada. Además, cuando cambia el tamaño de la ventana, todo lo que se está ejecutando en esa ventana recibe una SIGWINCHseñal que le permite lesssaber que debe verificar un nuevo tamaño de ventana. Por ejemplo, comencé a lessejecutar (como ID de proceso 16663), me conecté a él stracey cambié el tamaño de la ventana. Esto es lo que vi:

$ 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

Esto también es qué tput colsy tput lineshacer detrás de escena, si pueden. Para obtener más información sobre este método, consulte man tty-ioctly busque TIOCGWINSZ.

Sin embargo, para otros terminales, como los conectados a puertos serie, no hay forma de obtener esta información directamente. En ese caso, lesscomienza a buscar pistas en las variables de entorno.

  • LINESy COLUMNSa menudo se establecerá en las dimensiones del terminal. De hecho, si puede basho no zshpuede encontrar las dimensiones del terminal, establecerá automáticamente estas variables para facilitar que los programas no tan inteligentes vean el tamaño del terminal. Sin embargo, la mayoría de los otros shells, incluidos dashy tcsh, no establecen estas variables.
  • TERMgeneralmente se establece en el tipo de terminal, en cuyo caso la base de datos terminfo puede contener el tamaño esperado del terminal. Si tput rowsno puede usar el IOCTL (por ejemplo, si está conectado a través de un puerto serie), volverá a los valores registrados aquí. Para un terminal cuyo tamaño puede cambiar, esto es solo una suposición y es probable que esté equivocado.

Para obtener más información, consulte man tputel comando para controlar el terminal y man terminfouna lista de cosas que puede indicarle al terminal que haga.

Jander
fuente
La base de datos terminfo no hace lo que se indicó aquí. La respuesta de @ warl0ck, que contiene menos información, es más precisa.
Thomas Dickey
@ThomasDickey Tienes razón; todo lo que tiene son valores esperados. Corrigió mi respuesta; Gracias.
Jander
7

Si observa el código fuente, sabrá las lessllamadas ioctl()para recuperar el tamaño de la ventana en 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
margarita
fuente