【问题标题】:An xterm-compatible TTY color query command?与 xterm 兼容的 TTY 颜色查询命令?
【发布时间】:2017-07-31 22:45:39
【问题描述】:

这里是从https://github.com/rocky/bash-term-background 中提取的一些shell 代码,用于获取终端背景颜色。我想在 Python 中模仿这种行为,以便它也可以检索值:

stty -echo
# Issue command to get both foreground and
# background color
#            fg       bg
echo -ne '\e]10;?\a\e]11;?\a'
IFS=: read -t 0.1 -d $'\a' x fg
IFS=: read -t 0.1 -d $'\a' x bg
stty echo
# RGB values are in $fg and $bg

我可以翻译大部分内容,但我遇到问题的部分是echo -ne '\e]10;?\a\e]11;?\a'

我认为:

output = subprocess.check_output("echo -ne '\033]10;?\07\033]11;?\07'", shell=True)

在 Python 2.7 中将是一个合理的翻译,但我没有得到任何输出。在兼容 Xterm 的终端中以 bash 运行会给出:

rgb:e5e5e5/e5e5e6
rgb:000000/000000

但是在 python 中我什么也没看到。

更新:正如 Mark Setchell 所说,问题的一部分可能是在子进程中运行的。所以当我将python代码更改为:

 print(check_output(["echo", "-ne" "'\033]10;?\07\033]11;?07'"]))

我现在看到了 RGB 值输出,但只是在程序终止之后。所以这表明问题在于连接到我猜 xterm 正在异步发送的输出。

第 2 次更新:根据 meuh 的代码,我在 https://github.com/rocky/python-term-background 中放置了一个更完整的版本

【问题讨论】:

  • 你是否在下一行启动另一个完全独立的子进程来读取输出?
  • shell=True 建议是的。当我删除该参数时,我现在可以看到 xterm 的输出。但未在变量中捕获。所以可能我需要做的就是事先重定向标准输出并等待,或者弄清楚如何直接从终端连接读取。我已经修改了问题以包含这一新的重要信息。

标签: python bash tty xterm


【解决方案1】:

您只需将转义序列写入标准输出并在标准输入设置为原始模式后读取响应:

#!/usr/bin/python3
import os, select, sys, time, termios, tty

fp = sys.stdin
fd = fp.fileno()

if os.isatty(fd):
    old_settings = termios.tcgetattr(fd)
    tty.setraw(fd)
    print('\033]10;?\07\033]11;?\07')
    time.sleep(0.01)
    r, w, e = select.select([ fp ], [], [], 0)
    if fp in r:
        data = fp.read(48)
    else:
        data = None
        print("no input available")
    termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
    if data:
        print("got "+repr(data)+"\n")
else:
    print("Not a tty")

【讨论】:

  • 谢谢。这很接近。我在编辑中建议了两个容易解决的问题。还有一个我不确定我知道如何解决。首先,我们应该检查 stdin 是否是 tty。其次,读取应该有一个超时。最后一个问题是,在非 xterm 兼容的终端上,您会看到转义字符串回显,我不希望这样。
  • 嗯。也许我需要类似 POSIX shell stty -echo 命令的东西?
  • 我认为setraw() 已经清除了回显位。您可以查找 TERM 值并只接受您认识的那些,例如 xterm
  • 我认为另一个问题是,不能仅仅因为标准输入是标准输出的 tty,所以需要单独检查。另外,我发现我可以通过添加等于字符串长度的退格字符来隐藏输出。这与检查 TERM 变量一起可能是最好的。如果没有人有更好的想法,我会在一天内接受。
  • hmm,我认为有两个原因 1) 我们试图捕获的响应来自 echo 命令退出之后,所以如果那个 echo 是我们的子进程,我们永远看不到查询响应 2) 响应被发送到 stdin 而不是 stdout,并且Popen.stdin 不支持读取,只支持写入
猜你喜欢
  • 2020-03-31
  • 2018-03-15
  • 1970-01-01
  • 1970-01-01
  • 2016-04-07
  • 1970-01-01
  • 2020-02-29
  • 2016-07-27
  • 1970-01-01
相关资源
最近更新 更多