Python - 如何查看选项卡补全输出

4 投票
1 回答
779 浏览
提问于 2025-04-20 19:44

我该如何查看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 模块,或者使用 openptyforkpty 函数,而不是 subprocess。虽然这样做不够优雅和高级,但它确实能工作。

当然,一旦你开始读取bash的TTY输出,你也会开始听到终端的哔声和光标移动的字符;希望你准备好应对这些情况。

一个更好的解决方案是,不要试图在bash中发送标签,而是使用 compgen 来程序化地完成补全:

completions = subprocess.check_output('compgen -c l', shell=True).splitlines()

那个 -c 表示你只想要命令名称。你可以补全很多东西——目录、文件名、环境变量等等,任何可以在交互提示符下补全的内容。如果你想要在空命令行开始时补全的内容,我相信那是 -abc -A function(别名、内置命令、命令和函数),但具体细节请查看文档。

撰写回答