带有pexpect实例错误的简单扭曲服务器(twistd .tap)

时间:2010-02-17 18:36:28

标签: python twisted daemon pexpect

我一直在创建一个异步服务器套接字,使用twisted发送和重用xml。

该应用程序运行良好!但是因为我的主要目标是将它嵌入到init.d脚本中并使其在后台运行我决定将其转换为“扭曲的应用程序”以便使用twistd运行它

# from twisted.internet import reactor
from twisted.internet.protocol import ServerFactory
from twisted.protocols.basic import LineOnlyReceiver
from twisted.application import internet, service

from xml.etree import ElementTree as ET

from aMuleClass import amulecmd

class DialogueProtocol(LineOnlyReceiver):
    def connectionMade(self):
        print "Connected: %s" % self.transport.getPeer().host
def lineReceived(self, line):
    parsed= ET.XML(line)
    if parsed.attrib['type'] == 'request':
        if parsed.attrib['prompt'] == 'results':
            self.transport.write(self.factory.mule.results())
        elif parsed.attrib['prompt'] == 'downloads':
            self.transport.write(self.factory.mule.downloads())
        else:
            print "Invalid request: %s\n" % line
    else:
        query= parsed.attrib['value']
        if parsed.attrib['type'] == 'search':
            print "must search for %s" % query
            self.factory.mule.search(query)
        elif parsed.attrib['type'] == 'cancel':
            print "must cancel %s" % query
            self.factory.mule.command("cancel %s" % query)
        elif parsed.attrib['type'] == 'download':
            print "must download %s" % query
            self.factory.mule.command("download %s" % query)

class DialogueProtocolFactory(ServerFactory):
def __init__(self):
    self.protocol= DialogueProtocol
    self.mule= amulecmd()

def main():
factory= DialogueProtocolFactory()
port = 14000
#
daemon= internet.TCPServer(port, factory)
application= service.Application("aMuleSocket")
#
daemon.setServiceParent(application)

if __name__ == '__main__':
main()

使用“twistd -noy file”(debug)运行它可以正常工作。 问题是当我想要背景我的脚本! (“twistd -y file”)socket dosent响应并且日志被pexpect中的错误填充,这是在我的amulecmd类中导入的... pexpect与终端提示应用程序通信并将答案返回到套接字..

日志文件:

2010/02/17 19:54 +0200 [-] Log opened.
2010/02/17 19:54 +0200 [-] twistd 2.5.0 (/usr/bin/python 2.5.2) starting up
2010/02/17 19:54 +0200 [-] reactor class: <class          'twisted.internet.selectreactor.SelectReactor'>
2010/02/17 19:54 +0200 [-] Loading aMuleSocket.tac...
2010/02/17 19:54 +0200 [-] Starting parent
2010/02/17 19:54 +0200 [-] Loaded.
2010/02/17 19:54 +0200 [-] __builtin__.DialogueProtocolFactory starting on 2000
2010/02/17 19:54 +0200 [-] Starting factory <__builtin__.DialogueProtocolFactory instance at 0x82dbd8c>
2010/02/17 19:54 +0200 [__builtin__.DialogueProtocolFactory] Connected: 192.168.0.2
2010/02/17 19:54 +0200 [DialogueProtocol,0,192.168.0.2] Unhandled Error
Traceback (most recent call last):
File "/usr/lib/python2.5/site-packages/twisted/python/log.py", line 48, in      callWithLogger
 return callWithContext({"system": lp}, func, *args, **kw)
File "/usr/lib/python2.5/site-packages/twisted/python/log.py", line 33, in callWithContext
 return context.call({ILogContext: newCtx}, func, *args, **kw)
File "/usr/lib/python2.5/site-packages/twisted/python/context.py", line 59, in callWithContext
 return self.currentContext().callWithContext(ctx, func, *args, **kw)
File "/usr/lib/python2.5/site-packages/twisted/python/context.py", line 37, in callWithContext
 return func(*args,**kw)
--- <exception caught here> ---
File "/usr/lib/python2.5/site-packages/twisted/internet/selectreactor.py", line 139, in _doReadOrWrite
 why = getattr(selectable, method)()
File "/usr/lib/python2.5/site-packages/twisted/internet/tcp.py", line 362, in doRead
 return self.protocol.dataReceived(data)
File "/usr/lib/python2.5/site-packages/twisted/protocols/basic.py", line 149, in dataReceived
 self.lineReceived(line)
File "aMuleSocket.tac", line 19, in lineReceived
 self.transport.write(self.factory.mule.downloads())
File "/home/hecyra/amule_scripts/amule-remote-read-only/server/aMuleClass.py", line 60, in downloads
 list= self.command('show DL').splitlines()
File "/home/hecyra/amule_scripts/amule-remote-read-only/server/aMuleClass.py", line 42, in command
 self.prompt()
File "/home/hecyra/amule_scripts/amule-remote-read-only/server/aMuleClass.py", line 27, in prompt
 self.process.expect('aMulecmd')
File "/usr/lib/python2.5/site-packages/pexpect.py", line 1064, in expect
 return self.expect_list(compiled_pattern_list, timeout, searchwindowsize)
File "/usr/lib/python2.5/site-packages/pexpect.py", line 1116, in expect_list
 c = self.read_nonblocking (self.maxread, timeout)
File "/usr/lib/python2.5/site-packages/pexpect.py", line 656, in read_nonblocking
 if not self.isalive():
File "/usr/lib/python2.5/site-packages/pexpect.py", line 914, in isalive
raise ExceptionPexpect ('isalive() encountered condition where "terminated" is 0, but   there was no child process. Did someone else call waitpid() on our process?')
pexpect.ExceptionPexpect: isalive() encountered condition where "terminated" is 0,            but there was no child process. Did someone else call waitpid() on our process?

它可能是什么?我只需要背景这个脚本:(看起来很简单

1 个答案:

答案 0 :(得分:3)

您在守护之前会产生子进程。守护进程后,该子进程现在是init的子进程,而不是守护进程的子进程。

您需要子类from twisted.application.service import Service并在startService中生成子进程,该进程将在守护进程后调用。

ÁLa:Twisted network client with multiprocessing workers?

编辑:实施

我无法完全测试,因为我没有你的amulecmd,但尝试更像这样的事情:

#!/usr/bin/env python
# vim:ai:et:ts=2:sw=2:bg=dark
from twisted.internet import protocol
from twisted.protocols.basic import LineOnlyReceiver
from twisted.application import service


from xml.etree import ElementTree as ET

from aMuleClass import amulecmd

class DialogueProtocol(LineOnlyReceiver):
  def connectionMade(self):
    print "Connected: %s" % self.transport.getPeer().host
  def lineReceived(self, line):
    parsed= ET.XML(line)
    if parsed.attrib['type'] == 'request':
      if parsed.attrib['prompt'] == 'results':
        self.transport.write(self.factory.mule.results())
      elif parsed.attrib['prompt'] == 'downloads':
        self.transport.write(self.factory.mule.downloads())
      else:
        print "Invalid request: %s\n" % line
    else:
      query= parsed.attrib['value']
      if parsed.attrib['type'] == 'search':
        print "must search for %s" % query
        self.factory.mule.search(query)
      elif parsed.attrib['type'] == 'cancel':
        print "must cancel %s" % query
        self.factory.mule.command("cancel %s" % query)
      elif parsed.attrib['type'] == 'download':
        print "must download %s" % query
        self.factory.mule.command("download %s" % query)

class MyService(service.Service):
  def __init__(self,port=14000):
    self.port = port
  def startService(self):
    self.factory = protocol.Factory()
    self.factory.protocol = DialogueProtocol
    from twisted.internet import reactor
    reactor.callWhenRunning(self.startListening)
  def startListening(self):
    self.factory.mule = amulecmd()
    from twisted.internet import reactor
    self.listener = reactor.listenTCP(self.port,self.factory)
    print "Started listening"
  def stopService(self):
    self.listener.stopListening()

if __name__ == '__main__':
  pass
else:
  application = service.Application("aMuleSocket")
  services = service.IServiceCollection(application)
  MyService().setServiceParent(services)