gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 22:58:11 24 4
gpt4 key购买 nike

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

外壳:

$ my-app
1
2
3
...

wrapper.py:

import subprocess
subprocess.run(['my-app'])

执行wrapper.py:

$ python wrapper.py
1
2
3
...

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

但现在我需要在应用程序输出特定行时执行某些操作。想象一下,当输出行包含 4 时,我想运行任意 Python 代码:

$ python wrapper.py
1
2
3
4 <-- here I want to do something
...

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

$ python wrapper.py   <-- allowed only odd numbers
1
3
...

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

def filter_fn(line):
if line ...:
return line.replace(...
...

但是如何实现这一点呢?如何将此类或类似的函数挂接到 subprocess.run 调用中?

<小时/>

注意:我无法使用 sh库,因为它对 Windows 的支持为零。

最佳答案

如果您希望能够处理子进程的 stdout 或 stderr,只需传递 subprocess.PIPE对于参数 stdout (分别为stderr)。然后,您可以从子进程访问输出流 proc.stdout ,默认情况下为字节流,但您可以使用 universal_newlines = True 将其作为字符串获取。示例:

import subprocess
app = subprocess.Popen(['my-app'], stdout = subprocess.PIPE, universal_newlines = True)
for line in app.stdout:
if line.strip() == '4':
# special processing
else:
sys.stdout.write(line)

您必须注意的是,为了能够在子进程写入输出后立即对其进行处理,子进程必须在每行之后刷新输出。默认情况下,stdout 在定向到终端时是行缓冲的 - 每行都打印在换行符上 - 但在定向到文件或管道时是 大小缓冲,这意味着它仅每 8k 或 16k 刷新一次字符。

在这种情况下,无论您对调用者大小做什么,您只会在程序完成时获得标准输出。

关于python - 如何运行Python子进程和流,同时过滤stdout和stderr?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36277995/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com