我如何找到终端窗口的宽度

How do I find the width & height of a terminal window?

作为一个简单的例子,我想编写一个cli脚本,它可以在终端窗口的整个宽度上打印"="。

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

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

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


  • tput cols告诉您列数。
  • tput lines告诉您行数。


在bash中,$LINES$COLUMNS环境变量应该能够做到这一点。终端尺寸发生任何变化时,将自动设置。(即信号绞车信号)


还有coreutils的stty

1
2
$ stty size
60 120 # <= sample output

它将分别打印行数和列数或高度和宽度。

然后,可以使用cutawk提取所需的零件。

高度/线条是stty size | cut -d"" -f1,宽度/柱是stty size | cut -d"" -f2


1
2
yes = | head -n$(($(tput lines) * $COLUMNS)) | tr -d '
'


要在Windows CLI环境中执行此操作,我可以找到的最佳方法是使用模式命令并分析输出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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;
}

希望它有用!

注意:返回的高度是缓冲区中的行数,而不是窗口中可见的行数。有更好的选择吗?


在posix上,最终您希望调用EDOCX1(获取窗口大小)ioctl()调用。大多数语言都应该有某种包装。例如,在Perl中,您可以使用术语::大小:

1
2
3
use Term::Size qw( chars );

my ( $columns, $rows ) = chars \*STDOUT;


正如我在Liceus Answer中提到的,他的代码在非英语区域设置窗口中会失败,因为mode的输出可能不包含子字符串"columns"或"lines":

&mode command output

您可以在不查找文本的情况下找到正确的子字符串:

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

请注意,我甚至都不喜欢线,因为它不可靠(实际上我不在乎它们)。

编辑:根据有关Windows 8的评论(噢,你…),我认为这可能更可靠:

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

但是一定要测试出来,因为我没有测试。


受@pixelbatt答案的启发,这里有一个水平条,由tput带来,轻微滥用printf填充/填充和tr

1
printf"%0$(tput cols)d" 0|tr '0' '='

在某些情况下,您的行/行和列与正在使用的"终端"的实际大小不匹配。也许您可能没有"tput"或"stty"可用。

这里有一个bash函数,您可以使用它来直观地检查大小。这将工作多达140列x 80行。您可以根据需要调整最大值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
""${tens_args[@]}"
    echo"$digits"
}