如何从 PHP cli 获取 linux 控制台 $COLUMNS 和 $ROWS?
Posted
技术标签:
【中文标题】如何从 PHP cli 获取 linux 控制台 $COLUMNS 和 $ROWS?【英文标题】:How to get linux console $COLUMNS and $ROWS from PHP cli? 【发布时间】:2011-01-13 06:58:57 【问题描述】:我目前正在为 php 创建一个新的整洁的 CLI 库,我想弄清楚它正在运行的控制台的宽度/高度。
我已经尝试过很多方法,例如挖掘 $_ENV、exec("echo $COLUMNS") 等,但没有结果,而如果我在 bash 命令行中键入 echo $COLUMNS 或 $ROWS,它会整齐地显示值。
我需要做什么才能从 PHP 访问这个值?
我正在使用这样的 .sh 脚本:
#!/usr/bin/php -q
<?php
require_once('lib.commandline.php');
class HelloWorld extends CommandLineApp
public function main($args)
echo('O, Hai.');
更新 最终解决方案:
public function getScreenSize()
preg_match_all("/rows.([0-9]+);.columns.([0-9]+);/", strtolower(exec('stty -a |grep columns')), $output);
if(sizeof($output) == 3)
$this->settings['screen']['width'] = $output[1][0];
$this->settings['screen']['height'] = $output[2][0];
【问题讨论】:
所以,嗯.. 我知道已经快 10 年了,但你还有那个 CLI 库吗? GitHub? :-) 【参考方案1】:另一个不需要解析的shell选项是tput
:
$this->settings['screen']['width'] = exec('tput cols')
$this->settings['screen']['height'] = exec('tput lines')
【讨论】:
优秀。在挖掘如何从stty
获取这些信息时,我完全忘记了tput
。
超级!非常有用且温和地提醒您解决方案的优雅程度。
如果你安装了 Windows 版 Git,这个解决方案甚至可以在 Windows 上运行。另一种方法是解析mode con /status
。
注意:调整窗口大小后tput返回的值不会更新,但stty会【参考方案2】:
使用 PHP ncurses_getmaxyx
函数。
ncurses_getmaxyx (STDSCR, $Height, $Width)
以前:
http://php.net/manual/en/function.getenv.php
$cols = getenv('COLUMNS');
$rows = getenv('ROWS');
“正确”的方式可能是调用TIOCGSIZE
ioctl 来获取内核对窗口大小的想法,或者调用命令stty -a
并解析rows
和columns
的结果
【讨论】:
只想说,在 Mac OS X 上的 Terminal.app 中没有设置 COLUMNS 和 ROWS。我也遇到了不一致的问题(例如,它们在 irb 中工作,但不是在执行一个 ruby 脚本,&c)。 如果在程序运行时调整终端大小,环境变量也不会更新。 Getenv 确实不起作用,$_ENV 也不起作用但是感谢 stty -a 的提示,我会解析它:) 我喜欢我当前解决方案的可移植性 :) 并非所有的盒子都有 PHP 中的 ncurses,所以我希望它尽可能裸露 鉴于您是这个问题的获胜者,并且您的最佳建议目前是“实验”功能(他们的全部大写,不是我的),您能否花点时间在这里整合各种方法,并显示实际正确答案。特别是因为您提到 ioctl 方法是首选方法(没有说明为什么它最好),但您实际上并没有展示如何做到这一点。自我说明:与其抱怨这一点,不如等六个月,然后写一个非常好的答案。记得感谢乔写了一个答案,而不仅仅是遵守……【参考方案3】:$COLUMNS
和 $LINES
可能没有被导出到您的程序中。您可以在运行应用之前运行export LINES COLUMNS
,也可以直接获取此信息:
$fp=popen("resize", "r");
$b=stream_get_contents($fp);
preg_match("/COLUMNS=([0-9]+)/", $b, $matches);$columns = $matches[1];
preg_match("/LINES=([0-9]+)/", $b, $matches);$rows = $matches[1];
pclose($fp);
【讨论】:
【参考方案4】:我不知道,为什么需要grep
来解析stty
输出:它确实有一个单独的选项来报告“根据内核的行数和列数”。
单行,无错误处理:
list($rows, $cols) = explode(' ', exec('stty size'));
单行,假设两个行/列都为 0 以防出现问题并抑制任何错误输出:
list($rows, $cols) = explode(' ', @exec('stty size 2>/dev/null') ?: '0 0');
【讨论】:
【参考方案5】:也许这个link 可能是答案,您可以使用ANSI Escape 代码来做到这一点,通过使用echo
使用特定的Escape 代码序列,特别是“查询设备”,我找到了另一个链接here 详细解释。也许使用它可以让您获得屏幕的列和行...
【讨论】:
这个答案指向 2 个死链接。此外,这个答案没有解释如何在发送转义序列后获取控制台大小。【参考方案6】:作为记录,这是我的函数(PHP 7.2 及更高版本):
它适用于 Windows 和 Linux。如果出现错误,则返回 80。
在一些古怪或太小的值的情况下,它返回最小值(80)
ps:“mode con”确实返回行数,但它基于缓冲区而不是屏幕大小。
ps2:奇怪的是,如果我将它作为网站运行,它会返回 120(Windows 主机)。
function calculateColSize($min=80)
try
if (PHP_OS_FAMILY === 'Windows')
$a1 = shell_exec('mode con');
/*
* Estado para dispositivo CON:
* ----------------------------
* Líneas: 9001
* Columnas: 85
* Ritmo del teclado: 31
* Retardo del teclado: 1
* Página de códigos: 65001
*/
$arr = explode("\n", $a1);
$col = trim(explode(':', $arr[4])[1]);
else
$col = exec('tput cols');
/*
* 184
*/
catch (Exception $ex)
$col = 80;
【讨论】:
【参考方案7】:环境变量可以在$_ENV超级全局变量中找到。
echo $_ENV['ROWS'];
例如。
【讨论】:
“我已经尝试了很多方法,例如挖掘 $_ENV、exec("echo $COLUMNS") 等,但没有结果”,发帖人提到。以上是关于如何从 PHP cli 获取 linux 控制台 $COLUMNS 和 $ROWS?的主要内容,如果未能解决你的问题,请参考以下文章