相关疑难解决方法(0)

子进程命令的实时输出

我正在使用python脚本作为流体动力学代码的驱动程序.当运行模拟时,我subprocess.Popen用来运行代码,从stdout和stderr收集输出到subprocess.PIPE---然后我可以打印(并保存到日志文件)输出信息,并检查是否有任何错误.问题是,我不知道代码是如何进展的.如果我直接从命令行运行它,它会给我输出关于它在什么时间迭代,什么时间,下一个时间步骤是什么等等的输出.

有没有办法既存储输出(用于记录和错误检查),还产生实时流输出?

我的代码的相关部分:

ret_val = subprocess.Popen( run_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True )
output, errors = ret_val.communicate()
log_file.write(output)
print output
if( ret_val.returncode ):
    print "RUN failed\n\n%s\n\n" % (errors)
    success = False

if( errors ): log_file.write("\n\n%s\n\n" % errors)
Run Code Online (Sandbox Code Playgroud)

最初我正在run_command通过管道,tee以便副本直接进入日志文件,并且流仍然直接输出到终端 - 但这样我就不能存储任何错误(对我的知识).


编辑:

临时解决方案:

ret_val = subprocess.Popen( run_command, stdout=log_file, stderr=subprocess.PIPE, shell=True )
while not ret_val.poll():
    log_file.flush()
Run Code Online (Sandbox Code Playgroud)

然后,在另一个终端,运行tail -f log.txt(st log_file = 'log.txt').

python error-handling shell logging subprocess

165
推荐指数
8
解决办法
13万
查看次数

从subprocess.communicate()读取流输入

我正在使用Python subprocess.communicate()来从一个运行大约一分钟的进程中读取stdout.

如何stdout以流式方式打印出该流程的每一行,以便我可以看到生成的输出,但在继续之前仍然阻止流程终止?

subprocess.communicate() 似乎立刻提供所有输出.

python subprocess

75
推荐指数
3
解决办法
7万
查看次数

如何从subprocess.Popen中获取'实时'信息在python(2.5)中

我想以下列方式使用子进程模块:

  1. 创建一个可能需要很长时间才能执行的新流程.
  2. 捕获stdout(或者stderr,或者两者一起或分别捕获)
  3. 处理来自子进程的数据,可能在接收的每一行上触发事件(在wxPython中说)或者只是暂时将它们打印出来.

我已经用Popen创建了进程,但是如果我使用communication(),那么一旦进程终止,数据就会立刻出现在我面前.

如果我创建一个单独的线程,做了阻塞readline()myprocess.stdout(使用stdout = subprocess.PIPE)我不明白这种方法的任何行或者,直到进程终止.(无论我设置为bufsize)

有没有办法解决这个不可怕的问题,并且在多个平台上运行良好?

python subprocess stdout popen

46
推荐指数
2
解决办法
1万
查看次数

合并Python脚本的子进程'stdout和stderr,同时保持它们可区分

我想将python脚本的子进程'stdout和stdin指向同一个文件.我不知道的是如何使两个来源的线条区分开来?(例如,带有感叹号的stderr行前缀.)

在我的特定情况下,不需要对子进程进行实时监视,执行的Python脚本可以等待其执行结束.

python subprocess stdout stderr

32
推荐指数
4
解决办法
2万
查看次数

你能像往常一样制作python子进程输出stdout和stderr,还能将输出捕获为字符串吗?

可能重复:
包装子进程'stdout/stderr

这个问题中,hanan-n询问是否可以将python子进程输出到stdout,同时还将输出保存在字符串中以便以后处理.在这种情况下,解决方案是遍历每个输出行并手动打印它们:

output = []
p = subprocess.Popen(["the", "command"], stdout=subprocess.PIPE)
for line in iter(p.stdout.readline, ''):
    print(line)
    output.append(line)
Run Code Online (Sandbox Code Playgroud)

但是,此解决方案并未概括为您要为stdout和stderr执行此操作的情况,同时满足以下条件:

  • stdout/stderr的输出应分别转到父进程'stdout/stderr
  • 输出应该尽可能实时完成(但我最后只需要访问字符串)
  • stdout和stderr行之间的顺序不应该改变(我不太确定如果子进程以不同的时间间隔刷新它的stdout和stderr缓存,那怎么会工作;我们现在假设我们得到的所有东西都是包含完整的好块行?)

我查看了子进程文档,但找不到任何可以实现此目的的东西.我能找到的最接近的是添加stderr=subprocess.stdout和使用与上面相同的解决方案,但是我们失去了常规输出和错误之间的区别.有任何想法吗?我猜测解决方案 - 如果有的话 - 将涉及异步读取p.stdoutp.stderr.

这是我想做的一个例子:

p = subprocess.Popen(["the", "command"])
p.wait()  # while p runs, the command's stdout and stderr should behave as usual
p_stdout = p.stdout.read()  # unfortunately, this will return '' unless you use subprocess.PIPE
p_stderr = p.stderr.read()  # ditto
[do something …
Run Code Online (Sandbox Code Playgroud)

python subprocess

30
推荐指数
2
解决办法
3万
查看次数

Subprocess.Popen:将stdout和stderr克隆到终端和变量

是否可以修改以下代码以从'stdout'和'stderr'打印输出:

  • 印在终端上(实时),
  • 最后存储在outerrs变量中?

代码:

#!/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 subprocess popen python-3.x

22
推荐指数
2
解决办法
6034
查看次数

Python子进程将子输出到文件和终端?

我正在运行一个脚本,通过使用执行许多可执行文件

subprocess.call(cmdArgs,stdout=outf, stderr=errf)
Run Code Online (Sandbox Code Playgroud)

when outf/ errf是None或文件描述符(stdout/的不同文件stderr).

有什么方法可以执行每个exe,以便将stdout和stderr一起写入文件和终端?

python subprocess parent

16
推荐指数
1
解决办法
6764
查看次数

Python:使用附加的输入和输出文件提供和解析与外部程序之间的数据流

问题: 我有一个设计糟糕的Fortran程序(我无法更改它,我坚持使用它)从stdin和其他输入文件中获取文本输入,并将文本输出结果写入stdout和其他输出文件.输入和输出的大小非常大,我想避免写入硬盘驱动器(慢速操作).我编写了一个函数,迭代几个输入文件的行,我也有多个输出的解析器.我真的不知道程序是否首先读取所有输入然后开始输出,或者在读取输入时开始输出.

目标: 拥有一个为外部程序提供所需功能的函数,并在输出来自程序时解析输出,而无需将数据写入硬盘驱动器上的文本文件.

研究: 使用文件的天真方式是:

from subprocess import PIPE, Popen

def execute_simple(cmd, stdin_iter, stdout_parser, input_files, output_files):

    for filename, file_iter in input_files.iteritems():
        with open(filename ,'w') as f:
            for line in file_iter:
                f.write(line + '\n')


    p_sub = Popen(
        shlex.split(cmd),
        stdin = PIPE,
        stdout = open('stdout.txt', 'w'),
        stderr = open('stderr.txt', 'w'),
        bufsize=1
    )
    for line in stdin_iter:
        p_sub.stdin.write(line + '\n')

    p_sub.stdin.close()
    p_sub.wait()

    data = {}
    for filename, parse_func in output_files.iteritems():
        # The stdout.txt and stderr.txt is included here
        with open(filename,'r') as f: …
Run Code Online (Sandbox Code Playgroud)

python legacy io asynchronous

16
推荐指数
2
解决办法
1660
查看次数

如何在不使用communication()的情况下避免子进程中的死锁

proc = subprocess.Popen(['start'],stdin=subprocess.PIPE,stdout=subprocess.PIPE)
proc.stdin.write('issue commands')
proc.stdin.write('issue more commands')
output = proc.stdout.read()   # Deadlocked here

# Actually I have more commands to issue here 
Run Code Online (Sandbox Code Playgroud)

我知道communic()可以给我一个解决这个问题的方法,但我想稍后发出更多的命令.但是communication()有点关闭子进程.

这有什么知道的工作吗?我正在尝试使用python包装器与路由器进行交互.所以我有更多的命令出现,也可以产生一些输出.在那种情况下,如何在不终止子进程的情况下进行读取.

python deadlock subprocess stdout popen

10
推荐指数
1
解决办法
4241
查看次数

subprocess.Popen 处理标准输出和标准错误

我正在尝试同时处理stdoutstderrsubprocess.Popen通过捕获两者的调用处理,subprocess.PIPE但希望在输出时处理输出(例如在终端上打印它们)。

我见过的所有当前解决方案都将等待Popen调用完成以确保捕获所有stdoutstderr,以便可以对其进行处理。

这是一个带有混合输出的示例 Python 脚本,在实时(或尽可能实时)处理它时,我似乎无法复制订单:

$ cat mix_out.py

import sys

sys.stdout.write('this is an stdout line\n')
sys.stdout.write('this is an stdout line\n')
sys.stderr.write('this is an stderr line\n')
sys.stderr.write('this is an stderr line\n')
sys.stderr.write('this is an stderr line\n')
sys.stdout.write('this is an stdout line\n')
sys.stderr.write('this is an stderr line\n')
sys.stdout.write('this is an stdout line\n')
Run Code Online (Sandbox Code Playgroud)

一种似乎可行的方法是使用线程,因为这样读取将是异步的,并且可以按照subprocess产生输出的方式进行处理。

这个只是处理stdoutfirst 和stderrlast的当前实现,如果输出最初在两者之间交替,这可能是欺骗性的:

cmd = ['python', 'mix_out.py']

process = subprocess.Popen( …
Run Code Online (Sandbox Code Playgroud)

python subprocess

5
推荐指数
2
解决办法
2290
查看次数

子流程既输出到PIPE,又直接输出到stdout

我发现了许多看起来像我的问题,但是没有产生我可以使用的解决方案(最近的问题是:子进程输出到stdout和PIPE

问题:我想使用需要很长时间的子流程来启动流程。运行命令后,我需要解析stdout-output和stderr-output。

目前,我这样做如下:

p = subprocess.Popen( command_list, stdout=subprocess.PIPE, 
    stderr=subprocess.PIPE )
out, error_msg = p.communicate()
print out + "\n\n" + error_msg

#next comes code in which I check out and error_msg
Run Code Online (Sandbox Code Playgroud)

但是此方法的缺点是,用户在运行过程中看不到该过程的输出。仅在最后输出。

有没有一种方法可以在命令运行时打印输出(就像我给出的命令没有stdout / stderr = subprocess.PIPE一样),并且最终还是通过p.communicate输出?

注意:我目前正在使用python 2.5(使用此python版本的旧软件版本)进行开发。

python subprocess

5
推荐指数
1
解决办法
2389
查看次数

如何运行 Python 子进程和流,同时过滤 stdout 和 stderr?

我有一个类似服务器的应用程序,我想从 Python 运行。它永远不会停止,直到用户中断它。我想在应用程序运行时不断将 stdout 和 stderr 重定向到父级。幸运的是,这正是subprocess.run它的作用。

贝壳:

$ my-app
1
2
3
...
Run Code Online (Sandbox Code Playgroud)

wrapper.py

import subprocess
subprocess.run(['my-app'])
Run Code Online (Sandbox Code Playgroud)

执行wrapper.py

$ python wrapper.py
1
2
3
...
Run Code Online (Sandbox Code Playgroud)

我相信这要归功于subprocess.run从父进程继承 stdout 和 stderr 文件描述符这一事实。好的。

但是现在我需要在应用程序输出特定行时做一些事情。想象一下,当输出行包含4以下内容时,我想运行任意 Python 代码:

$ python wrapper.py
1
2
3
4   <-- here I want to do something
...
Run Code Online (Sandbox Code Playgroud)

或者我想从输出中删除一些行:

$ python wrapper.py   <-- allowed only odd numbers
1
3
...
Run Code Online (Sandbox Code Playgroud)

我以为我可以有一个过滤函数,我会以某种方式将其挂接到,subprocess.run并且它会在输出的每一行中被调用,无论它是 stdout 还是 stderr:

def filter_fn(line):
    if line …
Run Code Online (Sandbox Code Playgroud)

python subprocess python-3.x

2
推荐指数
2
解决办法
3856
查看次数

如何在运行 git 命令时获取子进程标准输出?

我有一个用 python 编写的程序并在其中使用了 git 命令。出于某种原因,我不想使用 git-python 或其他而不是子进程。但我目前被困在获取git clone输出上。

我试过一些代码片段。有些命令可以很好地使用ping 8.8.8.8,但不适用于git clone.

例如

使用线程

def log_worker(stdout):
    while True:
        last = non_block_read(stdout).strip() 
        if last != "":
            print(last)


def non_block_read(output):
    fd = output.fileno()
    fl = fcntl.fcntl(fd, fcntl.F_GETFL)
    fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
    try:
        return output.read()
    except:
        return ''

def test():
    mysql_process = subprocess.Popen(
        "ping google.com",
        shell=True,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE)

    thread = Thread(target=log_worker, args=[mysql_process.stdout])
    thread.daemon = True
    thread.start()

    mysql_process.wait()
    thread.join(timeout=1)

test()
Run Code Online (Sandbox Code Playgroud)

或者

newlines = ['\n', '\r\n', '\r']
def unbuffered(proc, …
Run Code Online (Sandbox Code Playgroud)

python git subprocess

0
推荐指数
1
解决办法
2056
查看次数