Как мне найти ширину и высоту окна терминала? - PullRequest
255 голосов
/ 05 ноября 2008

В качестве простого примера я хочу написать скрипт CLI, который может печатать '=' по всей ширине окна терминала.

#!/usr/bin/env php
<?php
echo str_repeat('=', ???);

или

#!/usr/bin/env python
print '=' * ???

или

#!/usr/bin/env bash
x=0
while [ $x -lt ??? ]; do echo -n '='; let x=$x+1 done; echo

Ответы [ 9 ]

478 голосов
/ 05 ноября 2008
  • tput cols сообщает количество столбцов.
  • tput lines сообщает количество строк.
87 голосов
/ 19 февраля 2009

В bash переменные окружения $LINES и $COLUMNS должны справиться с задачей. Будет установлено автоматически при любом изменении размера терминала. (т.е. сигнал SIGWINCH )

56 голосов
/ 11 ноября 2014

А есть stty, от coreutils

$ stty size
60 120 # <= sample output

Будет напечатано количество строк и столбцов или высота и ширина соответственно.

Затем вы можете использовать cut или awk, чтобы извлечь нужную часть.

Это stty size | cut -d" " -f1 для высоты / строк и stty size | cut -d" " -f2 для ширины / столбцов

15 голосов
/ 05 ноября 2008
yes = | head -n$(($(tput lines) * $COLUMNS)) | tr -d '\n'
12 голосов
/ 28 сентября 2011

Чтобы сделать это в среде CLI Windows, лучший способ найти способ - использовать команду mode и проанализировать вывод.

function getTerminalSizeOnWindows() {
  $output = array();
  $size = array('width'=>0,'height'=>0);
  exec('mode',$output);
  foreach($output as $line) {
    $matches = array();
    $w = preg_match('/^\s*columns\:?\s*(\d+)\s*$/i',$line,$matches);
    if($w) {
      $size['width'] = intval($matches[1]);
    } else {
      $h = preg_match('/^\s*lines\:?\s*(\d+)\s*$/i',$line,$matches);
      if($h) {
        $size['height'] = intval($matches[1]);
      }
    }
    if($size['width'] AND $size['height']) {
      break;
    }
  }
  return $size;
}

Надеюсь, это полезно!

ПРИМЕЧАНИЕ : Возвращенная высота - это количество строк в буфере, а не количество строк, видимых в окне. Есть ли лучшие варианты?

9 голосов
/ 10 апреля 2012

В POSIX, в конечном итоге, вы хотите вызвать TIOCGWINSZ (Get WINdow SiZe) ioctl(). У большинства языков должна быть какая-то обертка для этого. Например, в Perl вы можете использовать Term :: Size :

use Term::Size qw( chars );

my ( $columns, $rows ) = chars \*STDOUT;
4 голосов
/ 17 января 2014

Как я уже упоминал в ответе лицея, его код не будет работать в неанглийской локали Windows, потому что тогда вывод mode может не содержать подстрок "column" или "lines":

mode command output

Вы можете найти правильную подстроку без поиска текста:

 preg_match('/---+(\n[^|]+?){2}(?<cols>\d+)/', `mode`, $matches);
 $cols = $matches['cols'];

Обратите внимание, что я даже не беспокоюсь о строках, потому что они ненадежны (и я на самом деле их не волную).

Редактировать: Судя по комментариям о Windows 8 (о, ты ...), я думаю, что это может быть более надежным:

 preg_match('/CON.*:(\n[^|]+?){3}(?<cols>\d+)/', `mode`, $matches);
 $cols = $matches['cols'];

Проверьте это, хотя я не проверял.

1 голос
/ 17 апреля 2018

Вдохновленный ответом @ pixelbeat, вот горизонтальная полоса, созданная с помощью tput, незначительное неправильное использование printf заполнения / заполнения и tr

printf "%0$(tput cols)d" 0|tr '0' '='
0 голосов
/ 02 января 2019

В некоторых случаях ваши строки / строки и столбцы не соответствуют фактическому размеру используемого «терминала». Возможно, у вас нет доступных "tput" или "stty".

Вот функция bash, которую вы можете использовать для визуальной проверки размера. Это будет работать до 140 столбцов х 80 строк. Вы можете настроить максимумы по мере необходимости.

function term_size
{
    local i=0 digits='' tens_fmt='' tens_args=()
    for i in {80..8}
    do
        echo $i $(( i - 2 ))
    done
    echo "If columns below wrap, LINES is first number in highest line above,"
    echo "If truncated, LINES is second number."
    for i in {1..14}
    do
        digits="${digits}1234567890"
        tens_fmt="${tens_fmt}%10d"
        tens_args=("${tens_args[@]}" $i)
    done
    printf "$tens_fmt\n" "${tens_args[@]}"
    echo "$digits"
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...