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 |
- 我创建了这个微小的node.js lib来一致地获得正确的窗口大小npmjs.com/package/window-size
- tput cols告诉您列数。
- tput lines告诉您行数。
- "tput lines"似乎有效。
- echo -e"lines
cols"|tput -S要同时获取行和列,请参见:linux.about.com/library/cmd/blcmdl1_tput.htm
- tput是一个很好的命令,有许多命令用于读取终端的状态、控制光标和文本属性等。
- 例如,方便的别名:alias dim="echo $(tput cols)x$(tput lines)",这可能导致80x50。
- 此问题可能属于Unix或超级用户SE站点。
- 你现在是男人了,道格。
- tput有一个问题:没有--quiet选项可以让"unknown terminal"或"no value for$term"错误消息静音,2>/dev/null也会使其中断。Stty尺寸似乎更好。
- 伟大的回答!帮我很多忙。
- @当shell获得源代码时,将评估您提供的别名命令。别名命令需要使用单引号。像这样:alias dim='echo Terminal Dimensions: $(tput cols) columns x $(tput lines) rows'。
在bash中,$LINES和$COLUMNS环境变量应该能够做到这一点。终端尺寸发生任何变化时,将自动设置。(即信号绞车信号)
- 然而,这些环境变量只对bash可用,而对在bash内部运行的任何程序(如perl、python、ruby)都不可用。
- 是=head-n$(($lines*$columns))tr-d''
- 除了交互式的bash会话(如果您运行脚本,它将不再是交互式的)之外,它在任何情况下都不起作用。在脚本中唯一可以使用它的地方是bash中的prompt_命令。
- 实际上,如果您设置了checkwinsize选项,它在非交互脚本中也可以工作。例如,这个非交互脚本将打印运行它的终端的维度:shopt -s checkwinsize; (:); echo $LINES $COLUMNS(checkwinsize选项只在等待子shell完成后初始化变量,这就是我们需要(:)语句的原因)
- $LINES和$COLUMNS在发送SIGWINCH之后更新,实际上是在任何交互命令执行之后。如果你试图用trap SIGWINCH更新PS1,你就不能使用$LINES和$COLUMNS,它们会保留旧值。((
还有coreutils的stty。
1 2
| $ stty size
60 120 # <= sample output |
它将分别打印行数和列数或高度和宽度。
然后,可以使用cut或awk提取所需的零件。
高度/线条是stty size | cut -d"" -f1,宽度/柱是stty size | cut -d"" -f2。
- 本工作采用管式不能使用,suggest tput风格。
- 的问题是,这是不与tput总是可用的,而每一个tty stty中是可用的。这一信息,谢谢!
1 2
| yes = | head -n$(($(tput lines) * $COLUMNS)) | tr -d '
' |
- 不是问题的直接答案,而是一个很好的演示脚本。
- 多好的例子啊!
- 这么多年来我怎么会错过江户指挥部的?(FACEPALM)
- 这是什么语言?它看起来像一个有语法错误的shell脚本。(在shell中,赋值等号周围不能有空格,第一个管道似乎不合适。)
- yes '='将输出无限量的'='行,下面的命令组织起来足以填满终端。
- 很好的例子;如果你想要一个更加神秘的抨击:eval printf '=%.0s' {1..$[$COLUMNS*$LINES]}。
要在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;
} |
希望它有用!
注意:返回的高度是缓冲区中的行数,而不是窗口中可见的行数。有更好的选择吗?
- 难怪人们总是避开Windows控制台…
- 注意:这个命令的输出是特定于区域设置的。换句话说,这不会像在其他Windows区域设置中那样工作。这是我在windows7上得到的:i.imgur.com/wrr7swy.png
- 添加了一个带有解决方案的答案。不过1号!
在posix上,最终您希望调用EDOCX1(获取窗口大小)ioctl()调用。大多数语言都应该有某种包装。例如,在Perl中,您可以使用术语::大小:
1 2 3
| use Term::Size qw( chars );
my ( $columns, $rows ) = chars \*STDOUT; |
- 多谢你的帮助–指引我走向正确的方向。elixir::io.columnserlang:io:columns().erlang.org/doc/man/io.html columns-0
- 在posix标准中没有TIOCGWINSZ,ioctl()仅为过时的流功能定义。
正如我在Liceus Answer中提到的,他的代码在非英语区域设置窗口中会失败,因为mode的输出可能不包含子字符串"columns"或"lines":
&
您可以在不查找文本的情况下找到正确的子字符串:
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']; |
但是一定要测试出来,因为我没有测试。
- 您的方法在Win8中不起作用。我有不止一条---线。i.imgur.com/4X02DQT.png
- @马克,太好了,真漂亮。谢谢你,Windows。<3(更相关的是:我将了解如何解决这个问题……当Windows 9出现时:p)。
- 我就是这样做的:$mode = `mode`; list($rows, $cols) = array_slice(preg_split('/
/', substr($mode, strpos($mode, 'CON:'))), 2, 2);。然后我就把数字换掉了。
- @aleksandrmakov我想知道,如果有像CON device status:这样有顺序的语言会发生什么?也许匹配像CON.*:这样的东西会更好。
- 这是一camilomartin",那是"欺诈"的字符串。一.现场检查,我看到相同的结构。线是在第二行的在线"CON"后的字符串。第三列是在线。
- "你怎么知道它是aleksandrmakov在线所有的语言?我能想象到的CON可以解释最后的字是不可能在一些可用的语言。我想一定是是是是是CON在Word线和:末端。但是,这不可能是真的:我希望他们有P保持所有的命令行在英国。
- 嗯,我不是在所有通用的解决方案提供一个想法,我只是指出它的。
- "马克,你能告诉我如果这工作吗?
- 这看起来像是,是的。你能解释一下为什么你是在什么地方,|搜索?
- "我真的认为,马克是疑自己精确的事情。为什么我的真的是吗?有疑问的假设,我只是有一些原因和去与它,哈哈。
- mode是缓慢的。利用mode con /status是更快的,它只是把所有的excludes控制台调制解调器的状态。还不快但比照明,mode多单。另外,如果你用你的第一mode con /status,再好的作品,它只返回状态的控制台。
受@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"
} |