作为一个简单的例子,我想编写一个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
答案 0 :(得分:476)
tput cols
会告诉您列数。tput lines
告诉您行数。答案 1 :(得分:87)
在bash中,$LINES
和$COLUMNS
环境变量应该可以解决问题。将在终端大小发生任何变化时自动设置。 (即SIGWINCH信号)
答案 2 :(得分:55)
来自stty
$ stty size
60 120 # <= sample output
它将分别打印行数和列数,或高度和宽度。
然后,您可以使用cut
或awk
来提取所需的部分。
高度/行的stty size | cut -d" " -f1
和宽度/列的stty size | cut -d" " -f2
答案 3 :(得分:15)
yes = | head -n$(($(tput lines) * $COLUMNS)) | tr -d '\n'
答案 4 :(得分:12)
要在Windows CLI环境中执行此操作,我能找到的最佳方法是使用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;
}
我希望它有用!
注意:返回的高度是缓冲区中的行数,它不是窗口中可见的行数。还有更好的选择吗?
答案 5 :(得分:9)
在POSIX上,最终你想要调用TIOCGWINSZ
(Get WINdow SiZe)ioctl()
来电。大多数语言都应该有某种包装。例如,在Perl中,您可以使用Term::Size:
use Term::Size qw( chars );
my ( $columns, $rows ) = chars \*STDOUT;
答案 6 :(得分:4)
正如我在lyceus中提到的那样,他的代码在非英语区域设置Windows上会失败,因为mode
的输出可能不包含子串“columns”或“lines”:
您可以在不查找文本的情况下找到正确的子字符串:
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'];
虽然测试了,因为我没有测试它。
答案 7 :(得分:1)
受@ pixelbeat的回答启发,tput
带来了一个水平栏,轻微误用了printf
填充/填充和tr
printf "%0$(tput cols)d" 0|tr '0' '='
答案 8 :(得分:1)
这个shell代码使一个全局变量$TERM_SIZE
跟踪终端窗口的大小:
set_term_size() {
TERM_SIZE="$(stty size 2>/dev/null)" && [ "$TERM_SIZE" ] ||
TERM_SIZE='25 80'
}
trap set_term_size WINCH
set_term_size
它会尝试 stty size
,然后再回到假设终端是 25 行高和 80 个字符宽的假设。 POSIX 不要求 stty
` 使用 size
操作数,因此需要回退。
然后您可以使用 shell 的有限字符串替换功能访问 columsn 参数:
echo "${TERM_SIZE% *}" # Prints the terminal's height.
echo "${TERM_SIZE#* }" # Prints the terminal's width.
当然,您使用的脚本语言可能会提供一个库来为您处理这些问题——您应该使用它。
一旦知道终端的宽度,打印水平线就很容易了,例如,通过滥用 printf
的字符串填充:
printf '%*s\n' "${TERM_SIZE#* }" '' |
tr ' ' -
第一行告诉 printf
将与列数一样多的空格(通过滥用字符串 paddin)打印到管道中。请注意,POSIX 没有没有提到 *
语法,因此这可能不像上面的代码那样可移植。
第二行告诉 tr
从该管道中读取并用连字符替换每个空格。
答案 9 :(得分:0)
在某些情况下,您的行/行和列与所使用的“终端”的实际大小不匹配。也许您可能没有“ tput”或“ stty”。
这是一个bash函数,可用于直观地检查大小。最多可处理140列x 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"
}