Como é que menos conhece a resolução do terminal?

11

Sempre que alguém define um tamanho diferente para um console virtual, less reconhece a resolução da janela (suponho que ...); De acordo com isso, muda quantas linhas de texto deve visualizar. Como esse parâmetro é calculado?

    
por Giuseppe 01.10.2013 / 15:58

3 respostas

21

Se você está procurando uma maneira de verificar um script, você pode fazer uma destas:

  • Execute tput cols e tput lines , como sugere manatwork
  • verifique os valores de $ LINES e $ COLUMNS

Mas se você quiser os detalhes, aqui vamos nós:

Para terminais virtuais (xterm, et al) existe uma chamada de sistema ioctl() que lhe dirá qual o tamanho da janela. Se puder, less usa essa chamada. Além disso, quando você altera o tamanho da janela, o que está sendo executado nessa janela recebe um sinal SIGWINCH que permite que less saiba que deve procurar um novo tamanho de janela. Por exemplo, iniciei um less em execução (como ID de processo 16663), conectado a ele com strace e redimensionei a janela. Isso é o que eu 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

Isso também é o que tput cols e tput lines fazem nos bastidores, se puderem. Para mais informações sobre este método, consulte man tty-ioctl e procure por TIOCGWINSZ.

Para outros terminais, como aqueles conectados a portas seriais, não há como obter essa informação diretamente. Nesse caso, less começa a procurar por pistas nas variáveis de ambiente.

  • LINES e COLUMNS geralmente serão definidos para as dimensões do terminal. De fato, se bash ou zsh puder encontrar as dimensões do terminal, ele definirá essas variáveis automaticamente, para facilitar a visualização do tamanho do terminal por programas não tão inteligentes. No entanto, a maioria dos outros shells, incluindo dash e tcsh , não definem essas variáveis.
  • TERM é geralmente configurado para o tipo de terminal, em cujo caso o banco de dados terminfo pode conter o tamanho esperado do terminal. Se tput rows não puder usar o IOCTL (por exemplo, se você estiver conectado por uma porta serial), ele voltará aos valores registrados aqui. Para um terminal cujo tamanho pode mudar, isso é apenas um palpite e é provável que esteja errado.

Para mais informações, consulte man tput para o comando para controlar o terminal, e man terminfo para uma lista de coisas que você pode dizer ao terminal para fazer.

    
por 01.10.2013 / 16:34
6

Se você der uma olhada no código-fonte, saberá less calls ioctl() para recuperar o tamanho da janela no 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
    
por 01.10.2013 / 16:29
1

Não tenho certeza se esta é a informação que você está procurando. Eu acho que less registra um manipulador de sinal para SIGWINCH . Quando a dimensão do terminal muda, ele recebe um sinal SIGWINCH e testa a informação tty para a dimensão atual do terminal. link

    
por 01.10.2013 / 16:42

Tags