【问题标题】:Python readline module prints escape character during importPython readline 模块在导入期间打印转义字符
【发布时间】:2013-04-02 09:34:41
【问题描述】:

我在 Python 2.7.3 和 Fedora 17 中使用 readline 模块。我在 Ubuntu 12.10 上没有这个问题。

import readline 期间,会显示一个转义字符。

$ python -c 'import readline' |less
ESC[?1034h(END)

通常当我得到这样的意外输出时,我使用stdout/stderr 重定向到一个虚拟文件描述符来处理它(下面的示例)。但这一次,这个方法行不通了。

import sys

class DummyOutput(object):
    def write(self, string):
        pass

class suppress_output(object):
    """Context suppressing stdout/stderr output.
    """
    def __init__(self):
        pass
    def __enter__(self):
        sys.stdout = DummyOutput()
        sys.stderr = DummyOutput()
    def __exit__(self, *_):
        sys.stdout = sys.__stdout__
        sys.stderr = sys.__stderr__

if __name__ == '__main__':
    print 'Begin'
    with suppress_output():
        # Those two print statements have no effect
        # but *import readline* prints an escape char
        print 'Before importing'
        import readline
        print 'After importing'
    # This one will be displayed
    print 'End'

如果您在test.py 脚本中运行这个sn-p,您将看到在suppress_output 上下文中,print 语句确实被抑制,但不是转义字符。

$ python test.py |less
Begin
ESC[?1034hEnd
(END)

所以这是我的两个问题:

  1. 这个转义字符怎么可能通过?
  2. 如何抑制?

【问题讨论】:

  • 看起来模块想用转义序列改变终端状态,但这不起作用。你不应该尝试解决这个问题,而是解决它。
  • 是的,这里有一个基于 reinout.vanrees.org/weblog/2009/08/14/… 的解决方法。但这并没有回答我的第一个问题:)(我担心这不是很便携,但我可能错了)。
  • 我怀疑您的终端和/或 terminfo 数据库导致了这个问题。
  • 从我的 MacBook 和 TERM=xterm-256color SSH 连接到 RedHat 机器时,我遇到了这个问题。我相信这是一个 readline 设置错误。我现在能做的最好的就是使用export TERM=vt100 解决它。
  • 相关python bugbugs.python.org/issue19884

标签: python import stdout readline io-redirection


【解决方案1】:

这是我正在使用的(诚然基于@jypeter 的回答),仅当输出不进入 tty(例如被重定向到文件)时才清除 TERM 环境变量:

if not sys.stdout.isatty():

    # remember the original setting
    oldTerm = os.environ['TERM']

    os.environ['TERM'] = ''

    import readline

    # restore the orignal TERM setting
    os.environ['TERM'] = oldTerm

    del oldTerm

【讨论】:

    【解决方案2】:

    回答第一个问题:更改sys.stdout 实际上并不会影响stdout's file descriptor is pointing at 的文件,而是Python 认为是标准输出的高级文件对象。换句话说,更改 sys.stdout 会影响您的 Python 代码,但不会(通常)影响您可能正在使用的任何已编译扩展(如 readline 模块)。所有这些也适用于sys.stderr

    回答第二个问题:您可以按照this answer 的建议进行操作(应该可以直接移植到 Python)。尽管 cmets 中的建议听起来是更好的选择。

    【解决方案3】:

    在导入 readline 之前,我使用了以下 hack

    import os
    if os.environ['TERM'] == 'xterm':
        os.environ['TERM'] = 'vt100'
    # Now it's OK to import readline :)
    import readline
    

    【讨论】:

    • 问题也出现在xterm-256color
    • 但是设置os.environ['TERM'] = '' 然后导入readline 然后将os.environ['TERM'] 恢复到之前的状态可以避免打印转义序列(虽然不确定readline 的其他功能......)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-04
    • 1970-01-01
    • 2011-11-09
    • 1970-01-01
    • 2020-02-16
    • 1970-01-01
    • 2020-08-27
    相关资源
    最近更新 更多