Python 如何从子流程中筛选标准错误

Python 如何从子流程中筛选标准错误,python,subprocess,Python,Subprocess,我正在使用Popen运行一个外部进程。这里有一个故意简单的例子来说明ls写入标准输出,并写入每个缺失文件的标准错误: #!/usr/bin/env python3 import sys from subprocess import Popen, PIPE def test_process(*command): process = Popen(command) process.communicate() test_process('ls', '/etc/hosts', 'bad

我正在使用
Popen
运行一个外部进程。这里有一个故意简单的例子来说明
ls
写入标准输出,并写入每个缺失文件的标准错误:

#!/usr/bin/env python3
import sys
from subprocess import Popen, PIPE

def test_process(*command):
    process = Popen(command)
    process.communicate()

test_process('ls', '/etc/hosts', 'bad1', 'bad2', 'bad3')
输出如下:

/etc/hosts
ls: cannot access 'bad1': No such file or directory
ls: cannot access 'bad2': No such file or directory
ls: cannot access 'bad3': No such file or directory
但是,我想从标准错误中过滤掉某些行,因此我需要将一些内容传递到
Popen
构造函数的
stderr
参数中

根据Python文档(并通过在IDE中单步执行代码来确认),
stderr
参数只能是
PIPE
DEVNULL
、整数文件描述符或包装(有效)文件描述符的类文件对象。我尝试在
stderr
中创建一个类并传递一个新实例,以实现缺少的方法来进行过滤;但这不起作用,因为它的
fileno
方法必须返回实际的文件描述符

因此,我认为我需要传递stderr=PIPE,并在创建的管道的另一端进行过滤。这是我的尝试:

def test_process(*command):
    process = Popen(command, stderr=PIPE)
    output, error = process.communicate()
    if error:
        lines = error.decode().splitlines()
        for line in lines:
            if '2' not in line:
                print(line, file=sys.stderr)
然而,虽然我不希望标准错误包含很多行,但动态过滤它会更优雅。有没有什么方法可以让我编写一些Python代码,一次只接收一行代码,然后将其丢弃或传递?我想我可以创建一个新的子流程来进行过滤,并将另一个
Popen
链接到第一个子流程上,但这对于任务来说似乎相当繁重

我当然不想中断正在写入实际控制台的标准输出流,因此我不能像标准输出那样一次只读取标准错误中的一行


有更好的主意吗?

您需要流程中的
stdout
?当您同时需要两个StreamSye时,在没有死锁的情况下正确操作会有点困难。我正在将
tar
输出传送到
ssh
并在远程主机上解包,我想删除“This computer system is the property of”警告,因为当我连接到多个主机时,它会使输出混乱。因此,我希望看到写入
stdout
的所有内容,以及写入
stderr
的所有实际错误。