如何在Python中检测控制台是否支持ANSI转义码?
为了检测控制台是否正确 sys.stderr
或 sys.stdout
,我做了以下测试:
if hasattr(sys.stderr, "isatty") and sys.stderr.isatty():
if platform.system()=='Windows':
# win code (ANSI not supported but there are alternatives)
else:
# use ANSI escapes
else:
# no colors, usually this is when you redirect the output to a file
现在,通过运行此 Python 代码时,问题变得更加复杂IDE(如 PyCharm)。最近 PyCharm 添加了对 ANSI 的支持,但第一次测试失败:它具有 isatty
属性,但设置为 False
。
我想修改逻辑,以便它能够正确检测输出是否支持 ANSI 着色。一个要求是,在任何情况下,当输出重定向到文件时,我都不应该输出任何内容(对于控制台来说,这是可以接受的)。
更新
在 https://gist.github.com/1316877 添加了更复杂的 ANSI 测试脚本
In order to detect if console, correctly sys.stderr
or sys.stdout
, I was doing the following test:
if hasattr(sys.stderr, "isatty") and sys.stderr.isatty():
if platform.system()=='Windows':
# win code (ANSI not supported but there are alternatives)
else:
# use ANSI escapes
else:
# no colors, usually this is when you redirect the output to a file
Now the problem became more complex while running this Python code via an IDE (like PyCharm). Recently PyCharm added support for ANSI, but the first test fails: it has the isatty
attribute but it is set to False
.
I want to modify the logic so it will properly detect if the output supports ANSI coloring. One requirement is that under no circumstance I should output something out when the output is redirected to a file (for console it would be acceptable).
Update
Added more complex ANSI test script at https://gist.github.com/1316877
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Django 用户可以使用 django.core.management.color.supports_color 函数。
他们使用的代码是:
请参阅 https://github。 com/django/django/blob/master/django/core/management/color.py
Django users can use
django.core.management.color.supports_color
function.The code they use is:
See https://github.com/django/django/blob/master/django/core/management/color.py
我可以告诉你其他人是如何解决这个问题的,但这并不漂亮。如果您以 ncurses 为例(它需要能够在各种不同的终端上运行),您会发现它们使用 终端能力数据库,用于存储各种终端及其能力。关键是,即使他们也永远无法自动“检测”这些东西。
我不知道是否有跨平台 termcap,但可能值得您花时间寻找它。即使它在那里,它也可能没有列出您的终端,您可能必须手动添加它。
I can tell you how others have solved this problem, but it's not pretty. If you look at ncurses as an example (which needs to be able to run on all kinds of different terminals), you'll see that they use a terminal capabilities database to store every kind of terminal and its capabilities. The point being, even they were never able to automatically "detect" these things.
I don't know if there's a cross-platform termcap, but it's probably worth your time to look for it. Even if it's out there though, it may not have your terminal listed and you may have to manually add it.
\x1B[6n
是一个标准的(据我所知)ANSI 转义码,用于查询用户光标的位置。如果发送到标准输出,终端应将\x1B[{line};{column}R
写入标准输入。如果达到此结果,则可以假设支持 ANSI 转义码。主要问题是检测这个回复。Windows
msvcrt.getch
可用于从 stdin 检索字符,而无需等待按下 Enter 键。这与msvcrt.kbhit
结合使用,后者检测 stdin 是否正在等待读取,并生成在本文的带有注释的代码部分中找到的代码。Unix/with termios
警告:我(不明智地)没有测试这个特定的 tty/select/termios 代码,但过去知道类似的代码可以工作。
可以使用
tty.setraw
和select.select
复制getch
和kbhit
。因此,我们可以如下定义这些函数:然后可以将其与以下代码一起使用。
带注释的代码
带注释的完整代码
如果您需要,这里是原始代码。
来源
不分先后:
\x1B[6n
is a standard (as far as I am aware) ANSI escape code to query the position of the user's cursor. If sent to stdout, the terminal should write\x1B[{line};{column}R
to stdin. It can be assumed that ANSI escape codes are supported if this result is achieved. The main problem becomes detecting this reply.Windows
msvcrt.getch
can be used to retrieve a char from stdin, without waiting for enter to be pressed. This in combination withmsvcrt.kbhit
, which detects if stdin is waiting to be read yields code found in the Code w/ Comments section of this post.Unix/with termios
Warning: I have (inadvisably) not tested this specific tty/select/termios code, but have known similiar code to work in the past.
getch
andkbhit
can be replicated usingtty.setraw
andselect.select
. Thus we can define these functions as follows:This can then be used with the below code.
Code w/ Comments
Complete Code w/o Comments
In case you want it, here is the raw code.
Sources
In no particular order: