后台:我有一个连接到类似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
答案 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
感谢大家的好解决方案。希望这个例子可以帮助别人。 :)