是否可以修改以下代码以从'stdout'和'stderr'打印输出:
代码:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import subprocess
def run_cmd(command, cwd=None):
p = subprocess.Popen(command, cwd=cwd, shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
outs, errs = p.communicate()
rc = p.returncode
outs = outs.decode('utf-8')
errs = errs.decode('utf-8')
return (rc, (outs, errs))
Run Code Online (Sandbox Code Playgroud)
感谢@unutbu,特别感谢@ jf-sebastian,最终功能:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import sys
from queue import Queue
from subprocess import PIPE, Popen
from threading import Thread
def read_output(pipe, funcs):
for line in iter(pipe.readline, b''):
for func in funcs: …Run Code Online (Sandbox Code Playgroud) 我有以下大量的Python代码(运行v2.7)导致在MemoryError处理大(几GB)文件时抛出异常:
myProcess = Popen(myCmd, shell=True, stdout=PIPE, stderr=PIPE)
myStdout, myStderr = myProcess.communicate()
sys.stdout.write(myStdout)
if myStderr:
sys.stderr.write(myStderr)
Run Code Online (Sandbox Code Playgroud)
在阅读文档时Popen.communicate(),似乎有一些缓冲:
注意读取的数据缓冲在内存中,因此如果数据大小很大或不受限制,请不要使用此方法.
有没有办法禁用此缓冲,或强制缓存在进程运行时定期清除?
我应该在Python中使用什么替代方法来运行将千兆字节数据流式传输到的命令stdout?
我应该注意,我需要处理输出和错误流.
我有一个脚本,我想在python(2.6.5)中运行,遵循以下逻辑:
最后一个提示行包含我需要解析的文本(filename.txt).提供的响应无关紧要(只要我可以解析该行,程序实际上可以在不提供响应的情况下退出)
我的要求有点类似于在python脚本中包装交互式命令行应用程序,但是那里的响应看起来有点令人困惑,即使OP提到它不适合他,我仍然会挂起.
通过环顾四周,我得出的结论subprocess是这样做的最佳方式,但我遇到了一些问题.这是我的Popen系列:
p = subprocess.Popen("cmd", shell=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, stdin=subprocess.PIPE)
Run Code Online (Sandbox Code Playgroud)
当我打电话给read()或readline()打开时stdout,提示是打印机到屏幕并挂起.
如果我叫write("password\n")了stdin,提示被写入屏幕,它挂起.write()未写入文本(我没有光标移动新行).
如果我调用p.communicate("password\n"),与write()相同的行为
我在这里寻找一些关于输入的最佳方式的想法,stdin如果你感觉很慷慨,可能如何解析输出中的最后一行,尽管我最终可能会想到这一点.
我希望能够并行运行多个进程,并且能够随时使用stdout.我该怎么办?我是否需要为每个subprocess.Popen()呼叫运行线程,什么?
好的,我试图从python脚本运行一个C程序.目前我正在使用测试C程序:
#include <stdio.h>
int main() {
while (1) {
printf("2000\n");
sleep(1);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
模拟我将要使用的程序,它不断地从传感器获取读数.然后我试图"2000"从C程序读取输出(在这种情况下)与python中的子进程:
#!usr/bin/python
import subprocess
process = subprocess.Popen("./main", stdout=subprocess.PIPE)
while True:
for line in iter(process.stdout.readline, ''):
print line,
Run Code Online (Sandbox Code Playgroud)
但这不起作用.从使用print语句开始运行该.Popen行然后等待for line in iter(process.stdout.readline, ''):,直到我按下Ctrl-C.
为什么是这样?这正是我见过的大多数示例都是他们的代码,但它没有读取文件.
编辑:
有没有办法让它只在有东西被阅读时才能运行?
我有以下情况:我在socketio服务器上收到请求.我回答它(socket.emit(..))然后在另一个线程中启动一些计算负载很重的东西.
如果繁重的计算是由subprocess.Popen(使用subprocess.PIPE)引起的,它会完全阻止每个传入的请求,只要它正在被执行,尽管它发生在一个单独的线程中.
没问题 - 在这个线程中,建议异步读取子进程的结果,缓冲区大小为1,以便在这些读取之间,其他线程有机会做某事.不幸的是,这对我没有帮助.
我也已经monkeypatched eventlet和工作正常-只要我不使用subprocess.Popen与subprocess.PIPE在线程.
在此代码示例中,您可以看到它只在使用subprocess.Popen时发生subprocess.PIPE.当取消注释#functionWithSimulatedHeavyLoad()并反而评论functionWithHeavyLoad()一切都像魅力一样.
from flask import Flask
from flask.ext.socketio import SocketIO, emit
import eventlet
eventlet.monkey_patch()
app = Flask(__name__)
socketio = SocketIO(app)
import time
from threading import Thread
@socketio.on('client command')
def response(data, type = None, nonce = None):
socketio.emit('client response', ['foo'])
thread = Thread(target = testThreadFunction)
thread.daemon = True
thread.start()
def testThreadFunction(): …Run Code Online (Sandbox Code Playgroud) 我正在使用子进程模块调用外部程序(plink.exe)来登录服务器; 但是当我呼叫通信来读取输出时,它就是阻塞.代码如下:
import subprocess
process = subprocess.Popen('plink.exe hello@10.120.139.170 -pw 123456'.split(), shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print process.communicate() #block here
Run Code Online (Sandbox Code Playgroud)
我知道该块是因为plink.exe它仍在运行; 但我需要在子进程终止之前读取输出.反正有吗?
我正在使用该subprocess模块从python启动进程.我希望能够在写入/缓冲后立即访问输出(stdout,stderr).
例如,假设我想运行一个名为counter.pyvia a 的python文件subprocess.内容counter.py如下:
import sys
for index in range(10):
# Write data to standard out.
sys.stdout.write(str(index))
# Push buffered data to disk.
sys.stdout.flush()
Run Code Online (Sandbox Code Playgroud)
负责执行该counter.py示例的父进程如下:
import subprocess
command = ['python', 'counter.py']
process = subprocess.Popen(
cmd,
bufsize=1,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
Run Code Online (Sandbox Code Playgroud)
使用该counter.py示例,我可以在流程完成之前访问数据.这很棒!这正是我想要的.但是,删除该sys.stdout.flush()调用会阻止在我想要的时间访问数据.这是不好的!这正是我不想要的.我的理解是flush()调用强制将数据写入磁盘,在将数据写入磁盘之前,它只存在于缓冲区中.请记住,我希望能够运行任何进程.我不希望这个过程执行这种刷新,但我仍然期望数据可以实时(或接近它).有没有办法实现这个目标?
关于父进程的快速说明.您可能会注意到我正在使用bufsize=0线路缓冲.我希望这会导致每行的磁盘刷新,但它似乎不会那样工作.这个论点如何运作?
您还会注意到我正在使用subprocess.PIPE.这是因为它似乎是在父进程和子进程之间生成IO对象的唯一值.我通过查看模块中的Popen._get_handles方法得出了这个结论subprocess(我在这里指的是Windows定义).有两个重要的变量,c2pread而c2pwrite …
同样,同样的问题.
原因是 - 阅读以下内容后仍然无法使其正常工作:
我的情况是我有一个用C编写的控制台应用程序,让我们在循环中采用这个代码:
tmp = 0.0;
printf("\ninput>>");
scanf_s("%f",&tmp);
printf ("\ninput was: %f",tmp);
Run Code Online (Sandbox Code Playgroud)
它不断读取一些输入并写入一些输出.
我与它交互的python代码如下:
p=subprocess.Popen([path],stdout=subprocess.PIPE,stdin=subprocess.PIPE)
p.stdin.write('12345\n')
for line in p.stdout:
print(">>> " + str(line.rstrip()))
p.stdout.flush()
Run Code Online (Sandbox Code Playgroud)
到目前为止,每当我读取表单时,p.stdout它总是等待,直到进程终止然后输出一个空字符串.我尝试了很多东西 - 但结果仍然相同.
我尝试过Python 2.6和3.1,但版本没关系 - 我只需要让它在某个地方工作.
我需要在Python中使用它自己的专用TTY在一个单独的进程中运行一个交互式Bash实例(我不能使用pexpect).我使用了这个通常在类似程序中使用过的代码片段:
master, slave = pty.openpty()
p = subprocess.Popen(["/bin/bash", "-i"], stdin=slave, stdout=slave, stderr=slave)
os.close(slave)
x = os.read(master, 1026)
print x
subprocess.Popen.kill(p)
os.close(master)
Run Code Online (Sandbox Code Playgroud)
但是当我运行它时,我得到以下输出:
$ ./pty_try.py
bash: cannot set terminal process group (10790): Inappropriate ioctl for device
bash: no job control in this shell
Run Code Online (Sandbox Code Playgroud)
运行的Strace显示一些错误:
...
readlink("/usr/bin/python2.7", 0x7ffc8db02510, 4096) = -1 EINVAL (Invalid argument)
...
ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, 0x7ffc8db03590) = -1 ENOTTY (Inappropriate ioctl for device)
...
readlink("./pty_try.py", 0x7ffc8db00610, 4096) = -1 EINVAL (Invalid argument)
Run Code Online (Sandbox Code Playgroud)
代码片段看起来很简单,Bash没有得到它需要的东西吗?这可能是什么问题?
python ×10
subprocess ×7
popen ×4
pipe ×2
stdout ×2
bash ×1
blocking ×1
buffer ×1
c ×1
flask ×1
flush ×1
hang ×1
interactive ×1
linux ×1
memory ×1
python-2.x ×1
python-3.x ×1
stdin ×1
stream ×1
tty ×1