删除Python中所有子进程的输出而无需访问代码

时间:2017-08-25 12:18:38

标签: python subprocess stdout

在Python中我使用

sys.stdout = None 
在某些我无法控制的电话之前

。这些调用可能会调用一些写入stdout的子进程。

如何避免这些子进程调用写入stdout?

同样,我不拥有调用子流程的代码的所有权。 它似乎是subprocess.Popen(和类似的)并不尊重sys.stdout。

2 个答案:

答案 0 :(得分:1)

您可以使用抑制subprocess.Popenstdout的自定义函数替换stderr

import subprocess
import inspect

def Popen(*args, **kwargs):
    sig = inspect.signature(real_popen)
    bound_args = sig.bind(*args, **kwargs).arguments
    bound_args['stdout'] = subprocess.DEVNULL
    bound_args['stderr'] = subprocess.DEVNULL
    return real_popen(**bound_args)

real_popen = subprocess.Popen
subprocess.Popen = Popen

警告:

如果您有尝试读取进程输出的代码,它将失败。

答案 1 :(得分:0)

是的,重定向sys.stdout仅适用于python打印。当通过subprocess调用子进程时,python默认不捕获输出,并使进程正常执行。没有办法轻易地从过程中删除输出。

我认为您可以创建一个与您无法更改的python代码相同级别的subprocess.py文件(或在官方subprocess.py之前)更改Popen内容,但这意味着从您的存根模块导入官方模块,硬编码python路径,......可行,但有一个更简单的方法。

这是我测试过的python 3的快速入侵,其中有效:

  • 在python安装中找到文件subprocess.py并将其复制到您无法更改的模块旁边(在我的计算机上C:\python34\lib\subprocess.py
  • 在该文件中只添加一行

代码(第750行):

def __init__(self, args, bufsize=-1, executable=None,
             stdin=None, stdout=None, stderr=None,
             preexec_fn=None, close_fds=_PLATFORM_DEFAULT_CLOSE_FDS,
             shell=False, cwd=None, env=None, universal_newlines=False,
             startupinfo=None, creationflags=0,
             restore_signals=True, start_new_session=False,
             pass_fds=()):
    """Create new Popen instance."""

    _cleanup()

现在添加(_cleanup()之前):

    stderr = stdout = DEVNULL

强制标准输出和错误为null设备:无输出

现在的缺点是:

  • 依赖于已安装的python版本。可以与其他版本一起使用,但不建议混合使用。
  • 复制整个subprocess.py文件,而不仅仅是修补所需的电话

除此之外,这是一个5分钟的工作,它的工作原理。我建议您将其作为临时解决方案,并在某些时候对此“无法更改的代码”执行某些操作。