Python - 如何查看选项卡补全输出
我该如何查看TAB补全返回了什么?
我来解释一下:
假设我打开一个bash终端,输入l
然后按下TAB键。
这时我会看到所有包含l
这个字符的命令。
现在,我知道怎么通过编程的方式输入完整的命令到终端并解析输出,
比如:
def shell_output()
p = subprocess.Popen(command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
print iter(p.stdout.readline, '')
但是我该如何查看TAB补全显示了什么呢?
1 个回答
2
标签补全是读取模式的一部分。你只有在交互模式下,并且是在一个TTY设备上时,才能使用读取模式。所以,当你用 Popen
启动程序时,它的标准输入是一个管道,这样就无法使用标签补全了。
你可以通过不使用Python来测试这一点,方法如下:
$ socat TCP-LISTEN:12345 EXEC:bash &
$ nc localhost 12345
l<TAB>
什么也不会发生。你可能会在 L
后面看到 ^I
,或者7个空格,甚至什么都没有,但你不会得到任何补全的结果。
当然,你可以强制进入交互模式,但这样它只会打开 /dev/tty
,并忽略你的标准输入管道,这样也没有帮助。
所以,你需要做的是使用 pty
模块,或者使用 openpty
或 forkpty
函数,而不是 subprocess
。虽然这样做不够优雅和高级,但它确实能工作。
当然,一旦你开始读取bash的TTY输出,你也会开始听到终端的哔声和光标移动的字符;希望你准备好应对这些情况。
一个更好的解决方案是,不要试图在bash中发送标签,而是使用 compgen
来程序化地完成补全:
completions = subprocess.check_output('compgen -c l', shell=True).splitlines()
那个 -c
表示你只想要命令名称。你可以补全很多东西——目录、文件名、环境变量等等,任何可以在交互提示符下补全的内容。如果你想要在空命令行开始时补全的内容,我相信那是 -abc -A function
(别名、内置命令、命令和函数),但具体细节请查看文档。