作为一个简单的示例,我想编写一个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
作为一个简单的示例,我想编写一个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
Answers:
tput cols
告诉您列数。tput lines
告诉您行数。echo -e "lines\ncols"|tput -S
要获取行和列,请参阅:linux.about.com/library/cmd/blcmdl1_tput.htm
tput
是一个很棒的命令,其中包含许多用于读取终端状态,控制光标和文本属性等的命令。
alias dim="echo $(tput cols)x$(tput lines)"
,可能会导致80x50
。
alias dim='echo Terminal Dimensions: $(tput cols) columns x $(tput lines) rows'
在bash中,$LINES
和$COLUMNS
环境变量应该可以解决问题。端子尺寸的任何更改都会自动设置。(即SIGWINCH信号)
checkwinsize
选项,它确实可以在非交互式脚本中工作。例如,此非交互式脚本将打印运行该脚本的终端的尺寸:(shopt -s checkwinsize; (:); echo $LINES $COLUMNS
该checkwinsize
选项仅在等待子shell完成后才初始化变量,这就是我们需要该(:)
语句的原因)
$LINES
并$COLUMNS
在SIGWINCH
发送后(实际上是在执行任何交互式命令之后)进行更新。如果您尝试更新PS1
与trap SIGWINCH
您不能使用$LINES
与$COLUMNS
他们保持旧值((
LINES
并且COLUMNS
仅由bash 设置为shell变量。Bash不会将它们设置为环境变量,除非您导出这些shell变量。
yes = | head -n$(($(tput lines) * $COLUMNS)) | tr -d '\n'
tr
这些年来,我怎么想念命令?(facepalm)
yes '='
将输出无限数量的“ =”行,并且以下命令的组织足以填充终端
为此,在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;
}
我希望它有用!
注意:返回的高度是缓冲区中的行数,而不是窗口中可见的行数。还有更好的选择吗?
最终,在POSIX上,您想调用TIOCGWINSZ
(Get WINdow SiZe)ioctl()
调用。大多数语言都应该为此提供某种包装。例如在Perl中,您可以使用Term :: Size:
use Term::Size qw( chars );
my ( $columns, $rows ) = chars \*STDOUT;
TIOCGWINSZ
POSIX标准中没有,ioctl()
仅针对过时的STREAMS功能进行了定义。
正如我在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'];
不过请进行测试,因为我没有进行测试。
---
条线。i.imgur.com/4x02dqT.png
$mode = `mode`; list($rows, $cols) = array_slice(preg_split('/\n/', substr($mode, strpos($mode, 'CON:'))), 2, 2);
。然后我只替换数字以外的所有内容。
CON device status:
怎么办?也许匹配类似的东西CON.*:
会更好。
在某些情况下,您的行/行和列与所使用的“终端”的实际大小不匹配。也许您可能没有“ 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"
}