Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python与Cmd模块的Twisted集成_Python_Twisted_Stdin_Tab Completion_Python Cmd - Fatal编程技术网

Python与Cmd模块的Twisted集成

Python与Cmd模块的Twisted集成,python,twisted,stdin,tab-completion,python-cmd,Python,Twisted,Stdin,Tab Completion,Python Cmd,我喜欢Python的和。我想一起使用它们 我做了一些工作,但到目前为止,我还没有弄清楚如何使tab完成工作,因为我看不到如何在Twisted的LineReceiver中立即(不按Enter键)接收tab keypres事件 以下是我目前的代码: #!/usr/bin/env python from cmd import Cmd from twisted.internet import reactor from twisted.internet.stdio import StandardIO f

我喜欢Python的和。我想一起使用它们

我做了一些工作,但到目前为止,我还没有弄清楚如何使tab完成工作,因为我看不到如何在Twisted的LineReceiver中立即(不按Enter键)接收tab keypres事件

以下是我目前的代码:

#!/usr/bin/env python

from cmd import Cmd
from twisted.internet import reactor
from twisted.internet.stdio import StandardIO
from twisted.protocols.basic import LineReceiver

class CommandProcessor(Cmd):
    def do_EOF(self, line):
        return True

class LineProcessor(LineReceiver):
    from os import linesep as delimiter # makes newline work

    def __init__(self):
        self.processor = CommandProcessor()
        self.setRawMode()

    def connectionMade(self):
        self.transport.write('>>> ')

    def rawDataReceived(self, data):
        self.processor.onecmd(data)
        self.transport.write('>>> ')

StandardIO(LineProcessor())
reactor.run()
除了制表符完成之外,这在某种程度上是有效的。我可以输入像“help”这样的命令,Cmd模块将打印结果。但是我已经丢失了Cmd模块的漂亮标签完整功能,因为Twisted一次缓冲一行。我尝试将
LineProcessor.delimiter
设置为空字符串,但没有成功。也许我需要找一些其他的扭曲来代替LineReceiver?或者有一种更简单的方法可以避免我一个接一个地处理每个角色

我不能单独使用Cmd,因为我想让它成为一个网络应用程序,其中一些命令将导致发送数据,而从网络接收数据将异步进行(并显示给用户)


因此,无论我们是从上面的代码还是完全不同的代码开始,我都希望用Python构建一个友好的终端应用程序,它能够响应网络事件和制表符完成。我希望我可以使用已经存在的东西,而不必自己实现太多。

这种方法有一些困难:

  • Cmd.onecmd
    不会执行任何选项卡处理
  • 即使是这样,您的终端也需要处于cbreak模式,以便单独的击键进入Python解释器(
    tty.setcbreak
    可以解决这个问题)
  • 正如您所知,
    Cmd.cmdloop
    不支持反应器,将阻止等待输入
  • 然而,要获得您想要的所有酷行编辑,Cmd(实际上是readline)需要直接访问stdin和stdout
考虑到所有这些困难,您可能需要考虑让CommandProcessor在自己的线程中运行。例如:

#!/usr/bin/env python

from cmd import Cmd
from twisted.internet import reactor

class CommandProcessor(Cmd):
    def do_EOF(self, line):
        return True

    def do_YEP(self, line):
        reactor.callFromThread(on_main_thread, "YEP")

    def do_NOPE(self, line):
        reactor.callFromThread(on_main_thread, "NOPE")

def on_main_thread(item):
    print "doing", item

def heartbeat():
    print "heartbeat"
    reactor.callLater(1.0, heartbeat)

reactor.callLater(1.0, heartbeat)
reactor.callInThread(CommandProcessor().cmdloop)
reactor.run()

看一看,我注意到沙井和海螺,但它们对我所做的并没有多大意义。文档将Conch描述为一个SSHv2实现,包括客户机和服务器,并说明了如何创建一个SSH服务器,为其客户机着色。我的需求既相似又不同。如果你对如何使用沙井有更具体的建议,我洗耳恭听……其中一个问题是明显缺乏文档。我正在考虑自己在Tab键上调用Cmd模块中的完成方法。谢谢你指出cbreak,我不知道。我会试试你的方法,谢谢你写出来。不客气。基本上,readline是一个迷你curses应用程序。我认为,如果您试图调解对stdin/stdout的访问,您将不得不重新实现它的大部分功能。这个线程化方法让它直接管理stdin/stdout(包括cbreak模式),这应该保持简单。twisted.internet.threads.blockingCallFromThread是一个非常有用的twisted函数,它允许CommandProcessor获取返回值。