如何将tab键发送到python子进程的stdin

时间:2013-01-28 15:07:29

标签: python subprocess readline tab-completion

后台:我有一个连接到类似shell的应用程序的Python子进程,该应用程序使用readline库来处理输入,并且该应用程序有一个用于命令输入的TAB完成例程,就像庆典。产生了子进程,如下所示:

def get_cli_subprocess_handle():
    return subprocess.Popen(
                            '/bin/myshell',
                            shell=False,
                            stdin=subprocess.PIPE,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.STDOUT,
                            )

一切都很好,除了tab-complete。每当我的Python程序将制表符'\t'传递给子进程时,我在STDIN中获得5个空格,而不是触发readline库的制表符完成例程。 :(

问题:我可以向子进程的STDIN发送什么来触发子进程的tab-complete函数?也许问另一种方式:如何发送TAB 而不是TAB 字符 ,如果是甚至可能?

相关但未答复和出轨:

trigger tab completion for python batch process built around readline

3 个答案:

答案 0 :(得分:3)

类似应用程序的shell可能区分连接到stdin的终端和连接到它的管道。许多Unix实用程序只是为了优化它们的缓冲(行与块)而类似shell的实用程序可能会禁用批量输入(即PIPE)上的命令完成工具以避免意外结果。命令完成实际上是一个需要终端输入的交互式功能。

查看pty模块并尝试使用主/从对作为子进程的管道。

答案 1 :(得分:2)

确实没有将标签发送到管道。管道只能接受位串,如果制表符没有这样做,可能没有解决方案。

有一个类似名为pexpect的项目。只看它的interact()代码,我没有看到任何显而易见的东西使它工作而你的代码没有。鉴于此,最可能的解释是,pexpect实际上做了一些工作,使自己看起来像一个伪终端。也许您可以为此合并其代码?

答案 2 :(得分:1)

根据isedev's answer,我修改了我的代码,如下所示:

import os, pty

def get_cli_subprocess_handle():
    masterPTY, slaveTTY = pty.openpty()
    return masterPTY, slaveTTY, subprocess.Popen(
                                                 '/bin/myshell',
                                                 shell=False,
                                                 stdin=slaveTTY,
                                                 stdout=slaveTTY,
                                                 stderr=slaveTTY,
                                                 )

使用这个返回的元组,我能够根据需要执行select.select([masterPTY],[],[])os.read(masterPTY, 1024),并且我使用与pty模块中的私有方法非常相似的函数写入master-pty源:

def write_all(masterPTY, data):
    """Successively write all of data into a file-descriptor."""
    while data:
        chars_written = os.write(masterPTY, data)
        data = data[chars_written:]
    return data

感谢大家的好解决方案。希望这个例子可以帮助别人。 :)