如何以编程方式确定终端窗口中字符的尺寸?

7
我正在编写一个脚本,将在终端窗口中显示股票图表的ASCII艺术。我通常使用OSX/Terminal.app,但Linux解决方案也是可接受的替代方案。
我的脚本目前具有用于屏幕宽度和高度的命令行参数(再次以字符而不是像素为单位),默认值由我自己发明的环境变量确定。我希望这些脚本确定当前窗口的大小(以字符为单位),并将其用作默认值。我17英寸Macbook Pro上大窗口的典型大小可能是200 x 68。
这是一个perl脚本,但如果您知道其他语言的解决方案,请告诉我!
谢谢您的帮助。 Ken

你尝试过在谷歌上搜索“如何在Perl中获取终端大小”吗? - ewh
我尝试了其他类似的短语,但不是那个...那个确实揭示了 Perl 的解决方案。谢谢。 - Ken
3个回答

8

通常的做法是使用tput linestput cols命令,依次查询以下内容:

  • $LINES$COLUMNS 环境变量;
  • 由终端模拟器在调整窗口大小时设置的 termios 设置;
  • $TERM 标识的 terminfo 描述。

太好了!谢谢你,geekosaur!我实际上更喜欢这个解决方案,而不是使用Term::ReadKey的更perl-ish解决方案,因为这是一个我可以在perl脚本和bash脚本中都可以使用的解决方案。我写了很多这两种类型的脚本。 - Ken
perl:chomp(my $window_size_lines = tput lines);#同样适用于cols - Ken
tput lines 应该放在反引号中。我想我还没有学会如何在回复中发布代码片段。我在我的问题中使用了HTML的<pre>标签。但这里不起作用。 - Ken
在引用时请使用两个反引号。 (嗯,对了,在评论中无法显示)this `has` backticks - geekosaur
使用以下代码测试我的新知识,感谢! chomp(my $window_size_lines = `tput lines`); - Ken
这使我能够非常快速地使用“tput reset”来“修复”我的终端设置问题 :) - n611x007

2

如果你需要从C语言中访问终端窗口大小,可以使用TIOCGWINSZ选项调用/dev/ttyioctl系统调用。

Term::ReadKey模块可以提供此功能。参考man perlfaq8了解更多信息。

How do I get the screen size?

If you have Term::ReadKey module installed from CPAN, you can use it to fetch the width and height in characters and in pixels:

use Term::ReadKey;
($wchar, $hchar, $wpixels, $hpixels) = GetTerminalSize();

我感到有些内疚没有给你“最佳解决方案”的奖杯,因为正如所述,你的确提供了最好的解决方案。(我知道从perl调用bash命令是不被赞同的,我也这么认为。)我在问题中没有说的是,我还做了很多bash脚本编写,所以bash的“tput”命令对我来说实际上更加普遍适用。抱歉,无论我怎么选择,都无法安心入睡。 :) - Ken
所以你可以随意在bash中使用tput,但是当你在perl脚本中时,你真的应该使用Term::ReadKey方法,而不是分叉两个额外的命令;-) 另外,你可能还想调查捕获SIGWINCH信号的方法,该信号在终端窗口调整大小时发送。 - Alnitak

1

当以交互方式运行时,bash会定义$LINES$COLUMNS。否则,使用curses/ncurses来检索终端尺寸。


感谢您的及时和有益的回复!令我沮丧的是,我无法想出一种从perl中访问$LINES和$COLUMNS的方法。虽然它可以从交互式bash shell中获取,但它不是环境变量。我实际上编写了一个使用ncurses的window-size.c程序,这将是一个可接受的解决方案。再次感谢。 - Ken

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接