python-3.x - 将 STDOUT 提供给 stdout 会为 subprocess.run 返回 errno9
问题描述
我想允许我的程序的用户指定输出是否应该是详细的。即,运行子进程正在打印它们生成或不生成的所有输出。
我曾经能够做到:
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
我能够将错误缩小到:
subprocess.run(['ls','-la'],stdout=out)
即,定义输出应该去标准输出会导致这个问题。在早期(即,< 3.8)的 Python 中,情况并非如此。
这是设计使然吗?如何在不加倍 subprocess.run 调用的情况下仍然实现详细/非详细区别?
解决方案
您可以使用以下capture_output
选项:
如果 capture_output 为真,stdout 和 stderr 将被捕获。使用时,内部 Popen 对象会自动创建为 stdout=PIPE 和 stderr=PIPE。stdout 和 stderr 参数可能不会与 capture_output 同时提供。如果您希望捕获两个流并将其合并为一个,请使用 stdout=PIPE 和 stderr=STDOUT 而不是 capture_output。
subprocess.run(['ls','-la'], capture_output=not verbose)
stdout 参数采用 None、subprocess.PIPE、文件对象或文件描述符,但不是subprocess.STD_OUT
一个特殊值,表示 stderr 应该转到 stdout。
如果您希望子进程不打印任何内容并在内存中不保留任何内容,您也可以传递subprocess.DEVNULL
tostdout
和subprocess.STDOUT
to 。stderr
subprocess.run(
["ls", "-la"], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT
)
对于详细模式,默认值(两个参数都为 None)可以。您还可以传递sys.stdout
tostdout
和sys.stderr
to stderr
。所有这些都是等效的:
subprocess.run(
["ls", "-la"]
)
subprocess.run(
["ls", "-la"], stdout=None, stderr=None
)
subprocess.run(
["ls", "-la"], stdout=sys.stdout, stderr=sys.stderr
)
推荐阅读
- python - python - 使用键功能对序列进行排序
- ibm-cloud-infrastructure - 来自 GetConfiguration 的响应不返回 ItemCategory 信息
- javascript - 更改列表项的内容
- python - 比较多行python
- typescript - 在 RxJS 6 中为 Single、Maybe 和 Completable 创建类
- composer-php - 加载私有 git 仓库的 composer 依赖
- javascript - JSP 无法使用 webservlet doGet 使 AJAX 工作
- python - 从远程计算机使用 pyodbc 插入 SQL
- mongodb - 从一个聚合中的两个字段查找和分组
- instance - Godot引擎:删除场景实例而不释放整个场景