我尝试使用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
这不起作用,但感觉很接近。我完全失去了。到目前为止,感谢您的帮助!
答案 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()