Python 3.x 将标准输出提供给标准输出将返回subprocess.run的errno9

Python 3.x 将标准输出提供给标准输出将返回subprocess.run的errno9,python-3.x,subprocess,Python 3.x,Subprocess,我希望允许程序的用户指定输出是否应该是详细的。也就是说,运行子流程是否正在打印它们生成的所有输出 我过去能够做到: out = subprocess.DEVNULL if verbose: out = subprocess.STDOUT subprocess.run(['ls','-la'],stderr=out,stdout=out) 但这会导致以下错误: Traceback (most recent call last): File "<stdin>", line 1

我希望允许程序的用户指定输出是否应该是详细的。也就是说,运行子流程是否正在打印它们生成的所有输出

我过去能够做到:

out = subprocess.DEVNULL
if verbose:
   out = subprocess.STDOUT
subprocess.run(['ls','-la'],stderr=out,stdout=out)
但这会导致以下错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.8/subprocess.py", line 489, in run
    with Popen(*popenargs, **kwargs) as process:
  File "/usr/lib/python3.8/subprocess.py", line 854, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/usr/lib/python3.8/subprocess.py", line 1702, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
OSError: [Errno 9] Bad file descriptor
也就是说,定义输出应该转到标准输出导致了这个问题。在早期(即<3.8)Python中,情况并非如此


这是设计的吗?如何在不加倍子流程运行调用的情况下仍然实现详细/非详细的区别?

您可以使用
捕获\u输出
选项:

如果capture_输出为true,则将捕获stdout和stderr。使用时,内部Popen对象将自动创建为stdout=PIPE和stderr=PIPE。stdout和stderr参数不能与capture_输出同时提供。如果希望捕获并将两个流合并为一个流,请使用stdout=PIPE和stderr=stdout,而不是capture\u输出

stdout参数接受None、subprocess.PIPE、文件对象或文件描述符,但不接受
subprocess.STD_OUT
,它只是一个特殊值,指示stderr应该转到stdout

如果希望子进程不打印任何内容并在内存中不保留任何内容,还可以将
subprocess.DEVNULL
传递给
stdout
并将
subprocess.stdout
传递给
stderr

subprocess.run(
    ["ls", "-la"], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT
)
对于详细模式,两个参数的默认值都为“无”。您还可以将
sys.stdout
传递到
stdout
sys.stderr
传递到
stderr
。所有这些都是等效的:

subprocess.run(
    ["ls", "-la"]
)
subprocess.run(
    ["ls", "-la"], stdout=None, stderr=None
)
subprocess.run(
    ["ls", "-la"], stdout=sys.stdout, stderr=sys.stderr
)

如果我正确理解了capture_输出,它会将输出保存在python程序中的某个地方,以供以后评估。这不是我的意图,因为它应该直接传递给提示符(即,在发生不可恢复的错误时)。如果它为真,则是,但是如果它为False,它将直接传递到提示符。根据子进程的运行情况,这可能会导致我要防止的高内存负载。我编辑了andwer以解决您不希望在内存中保留任何内容的情况。
subprocess.run(
    ["ls", "-la"], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT
)
subprocess.run(
    ["ls", "-la"]
)
subprocess.run(
    ["ls", "-la"], stdout=None, stderr=None
)
subprocess.run(
    ["ls", "-la"], stdout=sys.stdout, stderr=sys.stderr
)