使用Twisted运行并返回shell命令的输出(查找)

时间:2018-02-06 21:52:00

标签: python linux twisted

我尝试使用Twisted作为后端,以允许用户使用shell命令搜索文件。

我遇到的问题是,当收到请求时,子进程会阻止新的扭曲请求并将这些请求排队。这可以防止我取消之前的请求以运行新的请求。

我已经尝试了一些解决这个问题的方法,我发现其他地方包括spawnprocess和尝试使用延迟。但是我无法找到返回输出的方法。任何帮助将不胜感激!

global child_pid
if child_pid is None:
    pass
else:
    for i in child_pid:
        try:
            i.kill()
        except Exception as e:
             pass

try:
    find_cmd = ("find '/var/log/' -type f -name '*.log' -newermt '2018-
        01-01 00:00:00' ! -newermt '2018-02-06 23:59:59'  -exec cat {} \+  2>&1")

    # run search command
    proc = subprocess.Popen(find_cmd, stdout=subprocess.PIPE,
        stderr=subprocess.PIPE, shell=True, preexec_fn=os.setsid)
    # record pid of process so new requests can kill the previous 
    # subprocess
    child_pid.append(proc)

    # check for output until process is done
    output = ''
    while True:
        line = proc.stdout.readline()
        output += '\n' + line
        if line == '' or proc.poll() is not None:
            break
    return output
except Exception as e:
    return 'Error', False

编辑:

谢谢!我觉得我越来越近了。它不再阻挡了。我仍然有点陷入困境,我不知道为什么它花了这么长时间来弄明白这一点...我读过这么多而且它没有下沉,我很沮丧,很可能没有帮助。

到目前为止,这是我可以更好地了解我想要实现的目标:

from __future__ import print_function
from os import environ
from twisted.internet.protocol import ProcessProtocol
from twisted.internet import reactor

class Collector(ProcessProtocol):
    def __init__(self):
        self.output = ""
        self.error = False
    def connectionMade(self):
        self.received = []

    def childDataReceived(self, fd, data):
        self.received.append(data)

    def processExited(self, reason):
        if 'code 0' in reason:
            print('0')
            self.error = False
        else:
            print('1')
            self.error = True
        reactor.stop()


def process_query(commands):
    if len(commands) > 0:
        return commands, 'success', True
    return commands, 'fail', False

def run_shell_command(commands):
    proto = Collector()
    find = reactor.spawnProcess(
        proto,
        commands[0],
        commands,
        env=environ,
    )
    reactor.callLater(.5, find.signalProcess, b"KILL")
    return proto.output, True

def format_output(output, commands):
    output_list = []
    try:
        output_list = output.split('\n')
        output_list.append(commands)
        return ouptut_list, True
    except:
        return '', False


def run_command(commands):
    response = {}
    message = ''
    result = True

    # format and validate parameters
    formatted_commands, message, result = process_query(commands)
    # where result is pass or failure of the command and message is reason
    if not result:
        response['message'] = message
        response['result'] = result
        return response
    shell_output, result = run_shell_command(formatted_commands)
    # where result is pass or failure of the command
    if not result:
        response['message'] = 'Error'
        return response
    formatted_output, result = format_output(shell_output, formatted_commands)
    response['data'] = formatted_output
    response['result'] = result
    if not result:
        response['message'] = 'Error'
        return response
    if len(formatted_output) < 1:
        response['message'] = 'No output found'
        response['result'] = False
        return response
    return response


cmd = [b"find", b"/var/log",
        b"-type", b"f",
        b"-name", b"*.log",
        b"-newermt", b"2018-01-01 00:00:00",
        b"!", b"-newermt", b"2018-02-06 23:59:59",
        b"-exec", b"cat", b"{}", b"+"]

x = run_command(cmd)
print(x)
reactor.run()

我一直在阅读有关延期的内容,他们似乎可以帮助我......可能是这样的:

 def run_command(commands):
    response = {}
    message = ''
    result = True

    formatted_commands, message, result = process_query(commands)
    if not result:
        response['message'] = message
        response['result'] = result
        return response

    shell_output = utils.getProcessOutput(formatted_commands)
    shell_output.addCallback(format_output, formatted_commands)

    response['data'] = shell_output
    response['result'] = True
    return response

这不起作用,但感觉很接近。我完全失去了。到目前为止,感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

from __future__ import print_function
from os import environ
from twisted.internet.protocol import ProcessProtocol
from twisted.internet import reactor

class Collector(ProcessProtocol):
    def connectionMade(self):
        self.received = []

    def childDataReceived(self, fd, data):
        self.received.append(data)

    def processExited(self, reason):
        print(reason)
        reactor.stop()

proto = Collector()
find = reactor.spawnProcess(
    proto,
    b"find",
    [
        b"find", b"/var/log",
        b"-type", b"f",
        b"-name", b"*.log",
        b"-newermt", b"2018-01-01 00:00:00",
        b"!", b"-newermt", b"2018-02-06 23:59:59",
        b"-exec", b"cat", b"{}", b"+",
    ],
    env=environ,
)
reactor.callLater(.5, find.signalProcess, b"KILL")
reactor.run()