linux - python subprocess.run 如果你重定向stdout/stderr,它会错误退出而不是工作
问题描述
#!/usr/bin/env python3
import subprocess
import os
if False:
# create log file.
kfd = os.open( 'kk.log', os.O_WRONLY )
# redirect stdout & err to a log file.
os.close(1)
os.dup(kfd)
os.close(2)
os.dup(kfd)
subprocess.run([ "echo", "hello world"], check=True )
% ./kk.py
hello world
%
以上工作正常,但如果您尝试编辑文件,并将 False 替换为 true:
% ./kk.py
% more kk.log
Traceback (most recent call last):
File "./kk.py", line 16, in <module>
subprocess.run([ "echo", "hello world"], check=True )
File "/usr/lib/python3.6/subprocess.py", line 418, in run
output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command '['echo', 'hello world']' returned
非零退出状态 1. %
我们没有得到输出,并且进程错误退出......我本来希望它能够正常工作,写入 kk.log。
解决方案
你可能想说这样的话:
#!/usr/bin/env python3
import subprocess
import os
if True:
# create log file.
kfd = os.open( 'kk.log', os.O_WRONLY | os.O_CREAT )
# redirect stdout & err to a log file.
os.dup2(kfd, 1)
os.dup2(kfd, 2)
subprocess.run([ "echo", "hello world"], check=True )
注意使用os.dup2
. 有两个原因。首先,生成的文件描述符是可继承的。您的 echo 实际上没有打开stdout
/-err
因此失败(您可以在 shell 中运行以下命令来回显,只需关闭 stdout 以检查行为:)/bin/echo hello world 1>&-
。另请注意,如果我关闭stdout
(1),则最低描述符(和 的结果os.dup
)可能并不总是正确的 1。有人可能stdin
在运行脚本之前关闭了您的 (0)(同样适用stderr
)。
文件描述符继承的背景故事在PEP-446中。
我还添加了os.O_CREAT
,因为我第一次尝试重现您的问题的失败是不存在的 kk.log。
不用说,除非尝试在操作系统中使用接口(也许作为练习),否则我想您通常应该坚持subprocess
自己。
推荐阅读
- sql - 如何编写查询以查找具有相似列的表?
- r - 在 R 中将 cURL 转换为 httr
- r - 从R中的shapefile中提取等距点
- string - 在代码中使用字符串作为常规文本
- html - 在 Eclipse 中使用速度 HTML 模板
- webpack - Preload Webpack 插件和 Webpack 4 出错
- javascript - POST 请求不返回节点中的表单下拉值
- python - Python字典什么都不显示
- javascript - 使用量角器为同一个硒测试用例使用多个 .properties 文件
- javascript - angular js href在url开头添加不安全