Python 3:捕获`\ x1b [6n`(`\ 033 [6n`,`\ e [6n`)ansi序列的返回

时间:2016-07-19 17:43:15

标签: python terminal python-3.4 ansi-escape

我写了一篇“libansi”。 我想捕获ansi序列的返回码\ x1b [6n 我尝试了一些解决方法,但无所事事。

例如:

#!/usr/bin/python3.4
rep = os.popen("""a=$(echo "\033[6n") && echo $a""").read()

代表返回“\ 033 [6n”...

有人有想法吗?

感谢您的帮助。

编辑: 我有一个部分解决方案:

a=input(print("\033[6n", end='')

但是我需要在输入上按“输入”以获得光标位置。

1 个答案:

答案 0 :(得分:0)

问题是

  1. 默认情况下,stdin是缓冲的
  2. 将序列写入stdout后,终端会将其响应发送给stdin,而不是发送到stdout。因此,终端就像按下实际按键而不返回一样。
  3. 诀窍是使用tty.setcbreak(sys.stdin.fileno(), termios.TCSANOW),然后在变量中通过termios.getattr存储终端属性以恢复默认行为。设置cbreakos.read(sys.stdin.fileno(), 1)即可立即从stdin读取。这也抑制了来自终端的ansi控制代码响应。

    def getpos():
    
        buf = ""
        stdin = sys.stdin.fileno()
        tattr = termios.tcgetattr(stdin)
    
        try:
            tty.setcbreak(stdin, termios.TCSANOW)
            sys.stdout.write("\x1b[6n")
            sys.stdout.flush()
    
            while True:
                buf += sys.stdin.read(1)
                if buf[-1] == "R":
                    break
    
        finally:
            termios.tcsetattr(stdin, termios.TCSANOW, tattr)
    
        # reading the actual values, but what if a keystroke appears while reading
        # from stdin? As dirty work around, getpos() returns if this fails: None
        try:
            matches = re.match(r"^\x1b\[(\d*);(\d*)R", buf)
            groups = matches.groups()
        except AttributeError:
            return None
    
        return (int(groups[0]), int(groups[1]))