如何将 python 子进程 stderr 和 stdout 重定向到多个文件? [复制]

2023-12-08

我只想将 stderr 和 stdout 重定向到多个文件。 例如: stderr 应重定向到 file_1 和 file_2。

我使用下面的方法将输出重定向到单个文件。

subprocess.Popen("my_commands",shell=True,stdout=log_file,stderr=err_file,executable="/bin/bash")

以上内容重定向stdout and stderr到单个文件。
任何人都可以告诉如何做同样的事情(将输出重定向到文件 log_file 和 err_file 例如stdout应重定向到 log_file 和 err_file 并且stderr应重定向到 err_file 和 new_file)


您可以创建自己的类似文件的类来写入多个文件句柄。这是一个简单的示例,其中包含重定向测试sys.stdout and sys.stderr.

import sys

class MultiOut(object):
    def __init__(self, *args):
        self.handles = args

    def write(self, s):
        for f in self.handles:
            f.write(s)

with open('q1', 'w') as f1, open('q2', 'w') as f2, open('q3', 'w') as f3:
    sys.stdout = MultiOut(f1, f2)
    sys.stderr = MultiOut(f3, f2)
    for i, c in enumerate('abcde'):
        print(c, 'out')
        print(i, 'err', file=sys.stderr)

运行该代码后,这些文件包含以下内容:

q1

a out
b out
c out
d out
e out    

q3

0 err
1 err
2 err
3 err
4 err    

q2

a out
0 err
b out
1 err
c out
2 err
d out
3 err
e out
4 err

FWIW,如果您愿意,您甚至可以这样做:

sys.stdout = MultiOut(f1, f2, sys.stdout)
sys.stderr = MultiOut(f3, f2, sys.stderr)

不幸的是,类似文件的对象MultiOut不能与Popen因为Popen通过底层操作系统文件描述符访问文件,即,它需要操作系统认为是文件的东西,因此只有提供有效的Python对象fileno方法可用于Popen的文件参数。

相反,我们可以使用 Python 3asyncio执行 shell 命令并同时复制其 stdout 和 stderr 输出的功能。

首先,这是一个简单的 Bash 脚本,我用它来测试以下 Python 代码。它只是循环遍历一个数组,将数组内容回显到 stdout,将数组索引回显到 stderr,就像前面的 Python 示例一样。

多重测试.bsh

#!/usr/bin/env bash

a=(a b c d e)
for((i=0; i<${#a[@]}; i++))
do 
    echo "OUT: ${a[i]}"
    echo "ERR: $i" >&2
    sleep 0.01
done

output

OUT: a
ERR: 0
OUT: b
ERR: 1
OUT: c
ERR: 2
OUT: d
ERR: 3
OUT: e
ERR: 4

下面是运行 multitest.bsh 的 Python 3 代码,将其 stdout 输出通过管道传输到文件 q1 和 q2,并将其 stderr 输出传输到 q3 和 q2。

import asyncio
from asyncio.subprocess import PIPE

class MultiOut(object):
    def __init__(self, *args):
        self.handles = args

    def write(self, s):
        for f in self.handles:
            f.write(s)

    def close(self):
        pass

@asyncio.coroutine
def copy_stream(stream, outfile):
    """ Read from stream line by line until EOF, copying it to outfile. """
    while True:
        line = yield from stream.readline()
        if not line:
            break
        outfile.write(line) # assume it doesn't block

@asyncio.coroutine
def run_and_pipe(cmd, fout, ferr):
    # start process
    process = yield from asyncio.create_subprocess_shell(cmd,
        stdout=PIPE, stderr=PIPE, executable="/bin/bash")

    # read child's stdout/stderr concurrently
    try:
        yield from asyncio.gather(
            copy_stream(process.stdout, fout),
            copy_stream(process.stderr, ferr))
    except Exception:
        process.kill()
        raise
    finally:
        # wait for the process to exit
        rc = yield from process.wait()
    return rc

# run the event loop
loop = asyncio.get_event_loop()

with open('q1', 'wb') as f1, open('q2', 'wb') as f2, open('q3', 'wb') as f3:
    fout = MultiOut(f1, f2)
    ferr = MultiOut(f3, f2)
    rc = loop.run_until_complete(run_and_pipe("./multitest.bsh", fout, ferr))
loop.close()
print('Return code:', rc)    

运行代码后,这些文件包含以下内容:

q1

OUT: a
OUT: b
OUT: c
OUT: d
OUT: e

q3

ERR: 0
ERR: 1
ERR: 2
ERR: 3
ERR: 4

q2

OUT: a
ERR: 0
OUT: b
ERR: 1
OUT: c
ERR: 2
OUT: d
ERR: 3
OUT: e
ERR: 4

asyncio 代码是从J.F.塞巴斯蒂安的回答对这个问题Subprocess.Popen:将 stdout 和 stderr 克隆到终端和变量。谢谢,J.F!

请注意,当数据可供调度的协程使用时,数据就会写入文件;确切地when发生这种情况取决于当前的系统负载。所以我把sleep 0.01multitest.bsh 中的命令使 stdout 和 stderr 行的处理保持同步。如果没有这种延迟,q2 中的 stdout 和 stderr 行通常不会很好地交错。可能有更好的方法来实现同步,但我仍然是异步编程的新手。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将 python 子进程 stderr 和 stdout 重定向到多个文件? [复制] 的相关文章

  • Python Popen 与 psexec 挂起 - 不良结果

    我对 subprocess Popen 和我认为是管道的问题有疑问 我有以下代码块 从 cli 运行时 100 都不会出现问题 p subprocess Popen psexec serverName get cmd c ver echo
  • django_openid_auth TypeError openid.yadis.manager.YadisServiceManager 对象不是 JSON 可序列化

    I used django openid auth在我的项目上 一段时间以来它运行得很好 但今天 我测试了该应用程序并遇到了这个异常 Environment Request Method GET Request URL http local
  • 如何使用 Plotly 中的直方图将所有离群值分入一个分箱?

    所以问题是 我可以在 Plotly 中绘制直方图 其中所有大于某个阈值的值都将被分组到一个箱中吗 所需的输出 但使用标准情节Histogram类我只能得到这个输出 import pandas as pd from plotly import
  • 从 ffmpeg 获取实时输出以在进度条中使用(PyQt4,stdout)

    我已经查看了很多问题 但仍然无法完全弄清楚 我正在使用 PyQt 并且希望能够运行ffmpeg i file mp4 file avi并获取流式输出 以便我可以创建进度条 我看过这些问题 ffmpeg可以显示进度条吗 https stack
  • 通过列表理解压平列表列表

    我正在尝试使用 python 中的列表理解来展平列表 我的清单有点像 1 2 3 4 5 6 7 8 只是为了打印这个列表列表中的单个项目 我编写了这个函数 def flat listoflist for item in listoflis
  • Django 模型在模板中不可迭代

    我试图迭代模型以获取列表中的第一个图像 但它给了我错误 即模型不可迭代 以下是我的模型和模板的代码 我只需要获取与单个产品相关的列表中的第一个图像 模型 py class Product models Model title models
  • 对图像块进行多重处理

    我有一个函数必须循环遍历图像的各个像素并计算一些几何形状 此函数需要很长时间才能运行 在 24 兆像素图像上大约需要 5 小时 但似乎应该很容易在多个内核上并行运行 然而 我一生都找不到一个有据可查 解释充分的例子来使用 Multiproc
  • TensorFlow的./configure在哪里以及如何启用GPU支持?

    在我的 Ubuntu 上安装 TensorFlow 时 我想将 GPU 与 CUDA 结合使用 但我却停在了这一步官方教程 http www tensorflow org get started os setup md 这到底是哪里 con
  • 如何从Python中的字符串中提取变量名称和值

    我有一根绳子 data var1 id 12345 name John White python中有没有办法将var1提取为python变量 更具体地说 我对字典变量感兴趣 这样我就可以获得变量的值 id和name python 这是由提供
  • Numpy 过滤器平滑零区域

    我有一个 0 及更大整数的 2D numpy 数组 其中值代表区域标签 例如 array 9 9 9 0 0 0 0 1 1 1 9 9 9 9 0 7 1 1 1 1 9 9 9 9 0 2 2 1 1 1 9 9 9 8 0 2 2 1
  • 按元组分隔符拆分列表

    我有清单 print L I WW am XX newbie YY ZZ You WW are XX cool YY ZZ 我想用分隔符将列表拆分为子列表 ZZ print new L I WW am XX newbie YY ZZ You
  • 首先对列表中最长的项目进行排序

    我正在使用 lambda 来修改排序的行为 sorted list key lambda item item lower len item 对包含元素的列表进行排序A1 A2 A3 A B1 B2 B3 B 结果是A A1 A2 A3 B
  • 在 Pandas 中使用正则表达式的多种模式

    我是Python编程的初学者 我正在探索正则表达式 我正在尝试从 描述 列中提取一个单词 数据库名称 我无法给出多个正则表达式模式 请参阅下面的描述和代码 描述 Summary AD1 Low free DATA space in data
  • Tkinter - 浮动窗口 - 调整大小

    灵感来自this https stackoverflow com a 22424245 13629335问题 我想为我的根窗口编写自己的调整大小函数 但我刚刚注意到我的代码显示了一些性能问题 如果你快速调整它的大小 你会发现窗口没有像我希望
  • Ubuntu 上的 Python 2.7

    我是 Python 新手 正在 Linux 机器 Ubuntu 10 10 上工作 它正在运行 python 2 6 但我想运行 2 7 因为它有我想使用的功能 有人敦促我不要安装 2 7 并将其设置为我的默认 python 我的问题是 如
  • 无法在前端使用 JavaScript Fetch API 将文件上传到 FastAPI 后端

    我正在尝试弄清楚如何将图像发送到我的 API 并验证生成的token那是在header的请求 到目前为止 这就是我所处的位置 app post endreProfilbilde async def endreProfilbilde requ
  • 您可以将操作直接应用于map/reduce/filter 中的参数吗?

    map and filter通常可以与列表理解互换 但是reduce并不那么容易被交换map and filter 此外 在某些情况下我仍然更喜欢函数语法 但是 当您需要对参数本身进行操作时 我发现自己正在经历语法体操 最终必须编写整个函数
  • 字典和数组作为类变量与实例变量

    这是赚取积分的简单方法 请解释以下内容 class C a b 0 c def init self self x def d self k v self x k v self a k v self b v self c append v d
  • 检查字典键是否有空值

    我有以下字典 dict1 city name yass region zipcode phone address tehsil planet mars 我正在尝试创建一个基于 dict1 的新字典 但是 它不会包含带有空字符串的键 它不会包
  • 您可以使用关键字参数而不提供默认值吗?

    我习惯于在 Python 中使用这样的函数 方法定义 def my function arg1 None arg2 default do stuff here 如果我不供应arg1 or arg2 那么默认值None or default

随机推荐