寻找终端宽度/高度的最佳方法? [英] Best way of finding terminal width/height?

查看:127
本文介绍了寻找终端宽度/高度的最佳方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好!


我使用python编写终端应用程序而且我一直很困扰

确定终端大小似乎有多难。什么是这样做的最佳方式?


最后我已经在Chuck Blake''ls''应用程序中加入了一个代码片段。

python。它似乎在我的计算机上做得很好,但很遗憾,

我不够时髦地把我的脑袋包裹在细粒度细节上

这一个。这个跨平台怎么样?是否有更多的pythonic方式来做这个?比如说:

来自ingenious_module的
导入terminal_info

cols,rows = terminal_info.size()


谢谢为你的时间(并感谢Chuck分享你的代码!)

/ Joel Hedlund

IFM生物信息学

Link?ping大学


Chuck Blake的terminal_size代码片段:

(来自 http://pdos.csail.mit.edu/~cblake/cls/cls.py)


def ioctl_GWINSZ(fd):#### TABULATION FUNCTIONS

尝试:###发现终端宽度

导入fcntl,termios,struct,os

cr = struct.unpack(''hh'',

fcntl.ioctl(fd,termios.TIOCGWINSZ,''1234''))

除了:

返回无

返回cr

def terminal_size():

###决定*某些*终端大小

#fit open f ds

cr = ioctl_GWINSZ(0)或ioctl_GWINSZ(1)或ioctl_GWINSZ(2)

如果不是cr:

#...那么ctty

试试:

fd = os.open(os.ctermid(),os.O_RDONLY)

cr = ioctl_GWINSZ(fd)< br $> b $ b os.close(fd)

除外:

通过

如果不是cr:

#env vars或最后默认值

尝试:

cr =(env [''LINES''],env [''COLUMNS''])

除外:

cr =(25,80)

#reverse rows,cols

return int(cr [1] ),int(cr [0])

解决方案

2006-02-05,Joel Hedlund< jo ******** **@gmail.com>写道:

我使用python编写终端应用程序,我一直对确定终端大小的难度感到困扰。这样做的最佳方式是什么?


您找到的代码中使用的方式。或者,你可以使用

ncurses,但如果你想要的只是

的终端窗口大小那就太大了。

最后我已经在python中包含了来自Chuck Blake''ls''
应用程序的代码片段。它似乎在我的comp上做得很好,但令人遗憾的是,我不够时髦地把头包裹起来
这个细粒的细节。


哪些细节?我们很乐意解释这些代码。不是那个

你需要了解使用代码的细节。

跨平台是怎么回事?


它适用于您可能遇到的任何Unix系统。我知道它可以在BSD,Solaris和Linux上运行。我不再支持
访问v7系统,但我很确定它也可以使用

- 除了我使用的那个没有'没有足够大的地址空间或磁盘驱动器来运行Python。


我不知道它是否可以在MS Windows上运行。

有更多的pythonic方式吗?


你找到的例子有什么不可思议的?对我来说,它看起来非常pythonic。使用或或或。当打开文件时,运算符
进行ioctl调用和try / except块

经典pythonic。

说出如下内容:

来自ingenious_module import terminal_info
cols,rows = terminal_info.size()




如果这是你想要的,请输入代码你找到了一个名为ingenious_module.py的文件

。尽管如此,我还没有看到

分层命名空间的重点。只需将其称为

terminal_info.py并执行


import terminal_info

cols,rows = terminal_info.terminal_size()


-

格兰特爱德华兹格兰特哇!哦,FISH棒,

在CHEEZ WHIZ,GIN fizz,

visi.com SHOW BIZ !!


>哪个细节?我们很乐意解释这些代码。不是

你需要了解使用代码的细节。


好​​的,为什么''1234''在这里,什么是'termios.TIOCGWINSZ',我应该如何

已经知道这是方式它也是吗?

fcntl.ioctl(fd,termios.TIOCGWINSZ,''1234'')


我在这里解释C结构,如果是的话 - 为什么python给我C

结构?不管怎么说'呃'?

struct.unpack(''hh'',...)


为什么0,1和2?

cr = ioctl_GWINSZ(0)或ioctl_GWINSZ(1)或ioctl_GWINSZ(2)

我不知道它是否可以在MS Windows上运行。


Linux和unix是我主要考虑的问题,但是知道它是否可以在Win / Mac上运行是很好的。


什么操作系统:es设置COLS / ROWS env变量?什么操作系统:es可以利用

termios模块?我有预感,我们在那里有100%的重叠,然后

这个解决方案让我在第一个方面(任意选择80 * 25)

其他操作系统: es(或者我错了?)。 Win / Mac人如何做到这一点?

你找到的例子是什么样的untythonic?




也许我做的有些差那里的措辞,但根据我的经验,python

通常具有高水平的抽象,它提供语言上的吸引力(如英语中的英文)解决几乎所有问题。比如

示例os.path.isfile(s)告诉我我的字符串s是否对应于

文件。我猜这就是我的意思。我希望在内置模块中找到类似于我的terminal_size()示例的

。我没想到必须要做那个结构fcntl ioctl boogey才能解决这个问题。

相对简单(?)的问题。


感谢您的帮助!

/ Joel


2006-02-05,Joel Hedlund< jo ***** *****@gmail.com>写道:

哪些细节?我们很乐意解释这些代码。不是那个
你需要了解使用代码的细节。
好的,为什么''1234''在这里,什么'termios.TIOCGWINSZ,




第二个问题:TIOCGWINSZ只是一个平台定义的

幻数,你传递给ioctl()告诉它你想要

到得到终端窗口大小:


终端IO控制获取WINdow SiZe

T IO CG赢SZ

我该怎么办?知道这是怎么做的呢?


因为如果你正在编写低级别的屏幕管理资源,你知道那些东西。顺便说一句:别忘了将

a处理程序附加到窗口大小更改信号(SIGWINCH),以便

您知道终端何时更改大小(这意味着您需要

调用该函数再次获取当前大小

重新布局你的屏幕。)

fcntl.ioctl(fd,termios .TIOCGWINSZ,''1234'')


现在是''1234''的问题。这一点_有点难看。 ioctl()

需要第三个参数,即

" write-like" ioctl()调用。如果ioctl()是一个类似读取的
调用,那么第三个参数只是一个字符串,用于指定ioctl调用预期的许多数据字节的数量。返回。在这个

的情况下,TIOGWINSZ ioctl将返回4个字节的数据(两个

16位整数),所以我们传递一个4字节的字符串来告诉

ioctl模块要为这个值分配多少内存

返回。


它在
http://docs.python.org/ lib / module-fcntl.html

我在这里解释C结构,


是的。我可以看到它可能被认为是非pythonic,但

它是一种常见的范式,即结构。模块是

包含在标准库中的那个任务。

如果是这样的话 - 为什么python给我C结构?


因为ioctl()是Unix的垃圾抽屉。它充满了

杂项废话,这在其他任何地方都不合适(而且往往是经过深思熟虑后的b / b
)。 python模块需要一个_lot_

非常讨厌的系统特定的知识和逻辑来暗示

找出传递和返回数据的类型。由于它没有那么多使用,所以没有人把所需的工作付诸实施,因为Python的ioctl模块无所不知。一些比较常见的

的东西可能是以更抽象的方式提供的。

那又是什么''hh''? struct.unpack(''hh'',...)


它指定了字段的类型。在结构中。

''h''表示一个短(16位)整数。结构从

返回ioctl()将包含两个16位整数。结构格式的完整

描述是

http://docs.python.org/lib/module-struct.html

为什么0,1和2?
cr = ioctl_GWINSZ(0)或ioctl_GWINSZ(1)或ioctl_GWINSZ(2)


0是标准输入的文件描述符,1是标准的

输出,2是标准错误。如果您的程序有一个

终端,其中一个可能连接到它。

我不知道如果它可以在MS Windows上运行。



Linux和unix是我主要关注的问题,但知道它是否可以在Win / Mac上运行会很好。




Homey不做Windows,所以你不得不问别人。

什么操作系统:es设置COLS / ROWS env vars?


无。有些shell设置了这些环境变量。他们可能会因为你的程序启动了b / b
终端的尺寸发生变化而错误。

什么操作系统:es可以利用termios模块?


我不知道你的意思是利用termios模块。

我有预感,我们在那里有100%的重叠,


没有comprende。

然后这个解决方案让我在其他操作系统的第一个方块(任意选择80 * 25):es (或者我错了?)。


Dunno。我已经使用Unix超过25年了。我曾几次试过Windows

,虽然它很糟糕。现在,Cygwin

在它周围稍微减少(但只是略微)。

Win / Mac人如何做到这一点?


AFAICT,Win / Mac人不会。


他们只是不写控制台程序。除非你在谈论关于Mac OS X的
,而且那只是BSD Unix,所以他们使用

ioctl()来做。
< blockquote class =post_quotes>

你找到的例子是什么样的uncythonic?



也许我在那里做了一些不好的措辞,但在我的体验python
通常具有高水平的抽象,它为几乎任何问题提供了语言上吸引人的(如英语中的解决方案)。




对于那些真实的流行和常见任务。对于没有人的东西

,你通常会回到底层平台

机制。

例如os.path.isfile如何( s)告诉我,我的字符串s
是否与文件相对应。我猜这就是我的意思。我希望在内置模块中找到像我的terminal_size()
这样的例子。


我猜想真正的答案是,很少有人会想要没有人曾经创建模块和

提交了它。随意...;)

我没想到要解决这个相对简单(?)问题的结构fcntl ioctl boogey




获取终端大小可能是一个简单的问题,但它只是一个复杂而艰巨的任务的小部分(管理
$ b) $ b全屏终端模式应用)。在python中编写

终端模式应用程序的人通常会做以下两件事之一:


1)只需编写一个类似Unix的正常文本处理过滤器 ;。

这些节目通常不关心终端尺寸

,因为它们可能根本没有连接到终端。


2)使用终端管理库,如ncurses + panel或

slang + newt。这样你就可以获得更高的等级。

抽象API。


-

格兰特爱德华兹格兰特哇!不要给我带来好感!!

at

visi.com


Hi all!

I use python for writing terminal applications and I have been bothered
by how hard it seems to be to determine the terminal size. What is the
best way of doing this?

At the end I''ve included a code snippet from Chuck Blake ''ls'' app in
python. It seems to do the job just fine on my comp, but regrettably,
I''m not sassy enough to wrap my head around the fine grain details on
this one. How cross-platform is this? Is there a more pythonic way of
doing this? Say something like:

from ingenious_module import terminal_info
cols, rows = terminal_info.size()

Thanks for your time (and thanks Chuck for sharing your code!)
/Joel Hedlund
IFM Bioinformatics
Link?ping University

Chuck Blake''s terminal_size code snippet:
(from http://pdos.csail.mit.edu/~cblake/cls/cls.py).

def ioctl_GWINSZ(fd): #### TABULATION FUNCTIONS
try: ### Discover terminal width
import fcntl, termios, struct, os
cr = struct.unpack(''hh'',
fcntl.ioctl(fd, termios.TIOCGWINSZ, ''1234''))
except:
return None
return cr

def terminal_size():
### decide on *some* terminal size
# try open fds
cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
if not cr:
# ...then ctty
try:
fd = os.open(os.ctermid(), os.O_RDONLY)
cr = ioctl_GWINSZ(fd)
os.close(fd)
except:
pass
if not cr:
# env vars or finally defaults
try:
cr = (env[''LINES''], env[''COLUMNS''])
except:
cr = (25, 80)
# reverse rows, cols
return int(cr[1]), int(cr[0])

解决方案

On 2006-02-05, Joel Hedlund <jo**********@gmail.com> wrote:

I use python for writing terminal applications and I have been
bothered by how hard it seems to be to determine the terminal
size. What is the best way of doing this?
The way used in the code you found. Alternatively, yould use
ncurses, but that''s massive overkill if all you want is the
terminal window size.
At the end I''ve included a code snippet from Chuck Blake ''ls''
app in python. It seems to do the job just fine on my comp,
but regrettably, I''m not sassy enough to wrap my head around
the fine grain details on this one.
Which details? We''d be happy to explain the code. Not that
you need to understand the details to use the code.
How cross-platform is this?
It will work on any Unix system you''re likely to encounter. I
know it works on BSD, Solaris, and Linux. I no longer yave
acces to a v7 system, but I''m pretty sure it would have worked
on that as well -- except the one I used didn''t have a large
enough address space or disk drive to run Python.

I don''t know if it will work on MS Windows or not.
Is there a more pythonic way of doing this?
What''s unpythonic about the example you found? It looks
extremely pythonic to me. The use of the "or" operator when
making ioctl calls and the try/except block when opening a file
is classically pythonic.
Say something like:

from ingenious_module import terminal_info
cols, rows = terminal_info.size()



If that''s what you want, put the code you found in to a file
named "ingenious_module.py". I don''t see the point of of
layering the namespace like that, though. Just call it
terminal_info.py and do

import terminal_info
cols,rows = terminal_info.terminal_size()

--
Grant Edwards grante Yow! Oh, FISH sticks,
at CHEEZ WHIZ, GIN fizz,
visi.com SHOW BIZ!!


> Which details? We''d be happy to explain the code. Not that

you need to understand the details to use the code.
OK, why ''1234'' in here, and what''s termios.TIOCGWINSZ, and how should I
have known this was the way too do it?
fcntl.ioctl(fd, termios.TIOCGWINSZ, ''1234'')

Am I interpreting C structs here, and if so - why is python giving me C
structs? And what''s ''hh'' anyway?
struct.unpack(''hh'', ... )

Why 0, 1 and 2?
cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
I don''t know if it will work on MS Windows or not.
Linux and unix are my main concerns, but it would be neat to know if it
would work on Win/Mac.

What OS:es set the COLS/ROWS env vars? What OS:es can leverage the
termios module? I have a hunch that we have 100% overlap there, and then
this solution leaves me at square one (arbitrary choice of 80*25) for
the others OS:es (or am I wrong?). How do Win/Mac people do this?
What''s unpythonic about the example you found?



Maybe I did bit of poor wording there, but In my experience python
generally has a high level of abstraction, which provides linguistically
appealing (as in "in english") solutions to almost any problem. Like for
example how os.path.isfile(s) tells me if my string s corresponds to a
file. I guess that''s what I mean really. I sort of expected to find
something like my terminal_size() example in the built-in modules. I
didn''t expect to have to do that struct fcntl ioctl boogey to solve this
relatively simple (?) problem.

Thanks for your help!
/Joel


On 2006-02-05, Joel Hedlund <jo**********@gmail.com> wrote:

Which details? We''d be happy to explain the code. Not that
you need to understand the details to use the code.
OK, why ''1234'' in here, and what''s termios.TIOCGWINSZ,



Second question first: TIOCGWINSZ is just a platform-defined
magic number that you pass to ioctl() to tell it that you want
to get the terminal window size:

Terminal IO Control Get WINdow SiZe
T IO C G WIN S Z
and how should I have known this was the way too do it?
Because if you''re writing low level screen management stuff for
Unix you know that sort of stuff. BTW: don''t forget to attach
a handler to the window-size-change signal (SIGWINCH) so that
you know when your terminal changes sizes (which means you need
to call the function to get the current size again and
re-layout your screen).
fcntl.ioctl(fd, termios.TIOCGWINSZ, ''1234'')
Now the ''1234'' question. This bit _is_ a bit ugly. ioctl()
expects a third parameter which is input data in the case of
"write-like" ioctl() calls. If the ioctl() is a "read-like"
call, the third argument is merely a string that specifies how
many data bytes the ioctl call is expected to return. In this
case the TIOGWINSZ ioctl will return 4 bytes of data (two
16-bit integers), so we pass it a 4 byte string to tell the
ioctl module how much memory to allocate for the value to be
returned.

It''s explained in more detail at

http://docs.python.org/lib/module-fcntl.html
Am I interpreting C structs here,
Yes. Which I can see might be considered "un-pythonic", but
it''s a common enough paradigm that the "struct" module is
included in the standard library for just that task.
and if so - why is python giving me C structs?
Because ioctl() is Unix''s junk-drawer. It''s full of
miscellaneous crap that didn''t fit anywhere else (and often was
an after-thought). The python module would require a _lot_ of
very nasty system-specific knowledge and logic to implicitly
figure out the types of passed and returned data. Since it''s
not used that much, nobody has put the work required to make
Python''s ioctl module omniscient. Some of the more common
stuff probably has been provided in a more abstract manner.
And what''s ''hh'' anyway? struct.unpack(''hh'', ... )
It''s specifying the types of the "fields" within the struct.
''h'' means a short (16-bit) integer. The struct returned from
the ioctl() is going to contain two 16-bit integers. The full
description of struct formats is at

http://docs.python.org/lib/module-struct.html

Why 0, 1 and 2?
cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
0 is the file descriptor for standard input, 1 is standard
output, and 2 is standard error. If your program has a
terminal, one of them may be connected to it.

I don''t know if it will work on MS Windows or not.



Linux and unix are my main concerns, but it would be neat to know if it
would work on Win/Mac.



Homey don''t do Windows, so you''ll have to ask somebody else that.
What OS:es set the COLS/ROWS env vars?
None. Some shells set those environment variables. They may
be wrong if the terminal has changed size since your program
was started.
What OS:es can leverage the termios module?
I don''t know what you mean by "leverage the termios module".
I have a hunch that we have 100% overlap there,
No comprende.
and then this solution leaves me at square one (arbitrary
choice of 80*25) for the others OS:es (or am I wrong?).
Dunno. I''ve been using Unix for 25+ years. I tried Windows a
few times and though it sucked rather badly. Now that Cygwin
is around it sucks slightly less (but only slightly).
How do Win/Mac people do this?
AFAICT, Win/Mac people don''t.

They just don''t write console programs. Unless you''re talking
about Mac OS X, and that''s just BSD Unix, so they do it using
ioctl().

What''s unpythonic about the example you found?



Maybe I did bit of poor wording there, but In my experience python
generally has a high level of abstraction, which provides linguistically
appealing (as in "in english") solutions to almost any problem.



For popular and common tasks that''s true. For stuff nobody
ever does, you usually fall back to the underlying platform
mechanism.
Like for example how os.path.isfile(s) tells me if my string s
corresponds to a file. I guess that''s what I mean really. I
sort of expected to find something like my terminal_size()
example in the built-in modules.
I would guess that the real answer is that so few people have
ever wanted it that nobody has ever created a module and
submitted it. Feel free... ;)
I didn''t expect to have to do that struct fcntl ioctl boogey
to solve this relatively simple (?) problem.



Getting terminal size may be a simple problem, but it''s only a
small part of a complex and difficult task (managing
"full-screen" terminal-mode apps). People who write
terminal-mode apps in python generally do one of two things:

1) Just write a normal Unix-like text processing "filter".
Those programs don''t generally care about the terminal size
since they may not be connected to a terminal at all.

2) Use a terminal management library like ncurses+panel or
slang+newt. That way you get a much higher level more
abstract API.

--
Grant Edwards grante Yow! Don''t SANFORIZE me!!
at
visi.com


这篇关于寻找终端宽度/高度的最佳方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆