在 python 中,如何检查 subprocess.Popen 对象的标准输出以获取任何要读取的内容?我正在围绕一个工具编写一个包装器,该工具有时会连续运行几个小时。当运行时间超过几分钟时,在子进程的标准输出上使用 .readline() 会严重降低脚本的速度。如果有任何内容需要阅读,我需要一种更有效地检查标准输出的方法。顺便说一句,这个特定的工具一次只能写入完整的行。脚本是这样的:
#!/usr/bin/python -u
#thiswrap.py
import sys, time
from subprocess import *
chldp = Popen(sys.argv[1], bufsize=0, stdout=PIPE, close_fds=True)
chstdin,chstdout=chldp.stdin,chldp.stdout
startnoti=False
while not chldp.poll():
rrl=chstdout.readline() # <--- this is where the problem is
if rrl[-8:]=='REDACTED TEXT':
sys.stdout.write(rrl[:-1]+' \r')
if not startnoti: startnoti=True
else:
if startnoti: sys.stdout.write('\n')
sys.stdout.write(rrl)
if startnoti: # REDACTED
time.sleep(0.1)
time.sleep(0.1)
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
说我写这个:
from subprocessing import Popen, STDOUT, PIPE
p = Popen(["myproc"], stderr=STDOUT, stdout=PIPE)
Run Code Online (Sandbox Code Playgroud)
现在,如果我这样做
line = p.stdout.readline()
Run Code Online (Sandbox Code Playgroud)
我的程序一直等到子进程输出下一行.
有没有什么魔法可以p.stdout让我可以读取输出,如果它在那里,但只是继续吗?我正在寻找类似的东西Queue.get_nowait()
我知道我可以创建一个读取线程p.stdout,但我们假设我无法创建新线程.
我是Tornado和Python Threads的新手.我想要实现的目标如下:我有一个Tornado Web服务器,它接收用户的请求.我想在本地存储一些数据,并将其定期写入数据库作为批量插入.
import tornado.ioloop
import tornado.web
import threading
# Keep userData locally in memory
UserData = {}
def background(f):
"""
a threading decorator
use @background above the function you want to thread
(run in the background)
"""
def bg_f(*a, **kw):
threading.Thread(target=f, args=a, kwargs=kw).start()
return bg_f
@background
def PostRecentDataToDBThread(iter = -1):
i = 0
while iter == -1 or i < iter:
#send data to DB
UserData = {}
time.sleep(5*60)
i = i + 1
class AddHandler(tornado.web.RequestHandler):
def post(self):
userID …Run Code Online (Sandbox Code Playgroud) 在Windows上的Python 3.4下,我需要通过子进程流式传输写入stdout/stderr的数据,即使用Python 3.4中引入的asyncio框架接收其输出.之后我还必须确定程序的退出代码.我怎样才能做到这一点?
我已经阅读了很多与此相关的问题并且学到了很多,但我仍然无法解决我的问题.我正在构建一个运行c ++可执行文件的wxPython应用程序,并实时显示该可执行文件中的stdout.我试图让这项工作遇到几个奇怪的结果.这是我目前的设置/问题:
//test.cc (compiled as test.out with gcc 4.5.2)
#include <stdio.h>
int main()
{
FILE* fh = fopen("output.txt", "w");
for (int i = 0; i < 10000; i++)
{
printf("Outputting: %d\n", i);
fprintf(fh, "Outputting: %d\n", i);
}
fclose(fh);
return 0;
}
#wxPythonScript.py (running on 2.7 interpreter)
def run(self):
self.externalBinary = subprocess.Popen(['./test.out'], shell=False, stdout=subprocess.PIPE)
while not self.wantAbort:
line = self.externalBinary.stdout.readline()
wx.PostEvent(self.notifyWindow, Result_Event(line, Result_Event.EVT_STDOUT_ID))
print('Subprocess still running')
print('Subprocess aborted smoothly')
Run Code Online (Sandbox Code Playgroud)
如果我运行上面的代码,子进程需要很长时间才能完成,即使它只需要写出数据并退出.但是,如果我运行以下内容,它会很快完成:
#wxPythonScript.py (running on 2.7 interpreter)
def run(self):
outFile = open('output.txt', 'r+') …Run Code Online (Sandbox Code Playgroud) 我遇到一种情况,我需要运行命令来adb shell获取设备的根访问权限。
然后,我使用以下命令在我的设备上运行交互式控制台应用程序:/oem/console --no-logging。
该命令返回以下输出:
之后,我需要按 ENTER 以便控制台接受事件(箭头光标已准备好接受调用事件)。这个控制台应用程序接受某些事件,我可以模拟我的设备的行为。例如:
invoke put.device.into.charge 1invoke call.cell.hangup 1invoke xyz所以我的问题是,如何将这些命令逐一输入到此控制台应用程序中,并在每个命令后等待几秒钟?
这是我到目前为止的代码:
def run_adb_shell_command(command, return_process=False):
"""Run an ADB shell command."""
cmd = command.split()
process = Popen(cmd, stdin=subprocess.PIPE)
if return_process:
return process
def send_command_to_console_app(command, process):
"""SEND Commands to Console App."""
new_line = '\n'.encode()
# encoded_command = str(command).encode()
s0 = command
s1 = 'event 1'
s2 = 'event 2'
s3 = 'event 3'
concat_query = "{}\n".format(s0)
process.communicate(input=concat_query.encode('utf-8'))[0]
process.kill()
Run Code Online (Sandbox Code Playgroud)
问题是,当communicate() …
我目前正在使用Python模块Spynner来自动执行一些Web任务.我遇到了一个问题,虽然由于某种原因,该过程只是停止移动,冻结但仍然响应Windows.
我想要做的是设置某种形式的监视器来检查并查看是否发生这种情况,然后重新启动该过程.我在考虑可能监视程序的终端输出,如果它在一定时间后停止推送数据,它会杀死程序并重新启动.
我知道如何杀死程序并再次运行它,只需使用操作系统和子进程,但我不知道如何设置监视终端是否停止在特定时间内发送数据.
我在Ubuntu 18.04上将Flask 1.0.2与Python 3.6一起使用。我的应用程序应使用asyncio并asyncio.create_subprocess_exec()启动后台脚本,从中读取stdout,然后在脚本完成后返回状态。
我基本上是想从这篇文章中实现一个答案: 在Python的subprocess.PIPE上非阻塞读取
该脚本已成功启动,并且从中获得了所有预期的输出,但是问题是它从不返回(意味着Killing subprocess now从不到达该行)。当我ps从Linux终端检查进程列表()时,后台脚本已退出。
我在做什么错,如何才能成功摆脱困境async for line in process.stdout?
导入后,在文件顶部,创建事件循环:
# Create a loop to run all the tasks in.
global eventLoop ; asyncio.set_event_loop(None)
eventLoop = asyncio.new_event_loop()
asyncio.get_child_watcher().attach_loop(eventLoop)
Run Code Online (Sandbox Code Playgroud)
我在路线上方定义了异步协程:
async def readAsyncFunctionAndKill(cmd):
# Use global event loop
global eventLoop
print("[%s] Starting async Training Script ..." % (os.path.basename(__file__)))
process = await asyncio.create_subprocess_exec(cmd,stdout=PIPE,loop=eventLoop)
print("[%s] Starting to read stdout ..." % (os.path.basename(__file__)))
async for line in process.stdout:
line = line.decode(locale.getpreferredencoding(False)) …Run Code Online (Sandbox Code Playgroud) python ×8
subprocess ×3
python-3.x ×2
android ×1
asynchronous ×1
asyncio ×1
c ×1
c++ ×1
crash ×1
flask ×1
linux ×1
pipe ×1
popen ×1
python-3.4 ×1
readline ×1
spynner ×1
stdout ×1
tornado ×1
wxpython ×1