python subprocess.run如果您重定向stdout / stderr,则错误退出而不是工作

时间:2018-07-08 18:34:46

标签: linux python-3.x subprocess

  import React, { Component } from 'react';
  import './Cool.css';
  import data from './data.json';
  import ReactBodymovin from 'react-bodymovin';

  class AventadorPage extends Component {
  render() {

    var bodymovinOptions = {
        loop: 2,
        autoplay: true,
        prerender: true,
        animationData: data,
    }

    return (
        <div id="main-container">
            <div className="animation">
                <ReactBodymovin options={bodymovinOptions} />
            </div>
        </div>
    );
}
}

export default AventadorPage;

上面的方法工作正常,但是如果您尝试编辑文件,并将False替换为true:

#!/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
% 

非零退出状态1。    %

我们没有得到输出,并且过程错误退出了... 我希望它能正常工作,写给kk.log。

1 个答案:

答案 0 :(得分:0)

您可能想改成这样:

#!/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。这有两个原因。首先,生成的文件描述符是可继承的。您的回声实际上没有打开stdout / -err并因此失败了(您可以在shell中运行以下命令以仅关闭stdout进行回声以检查行为:/bin/echo hello world 1>&-)。另请注意,如果我关闭stdout(1)时,最低描述符(和os.dup的结果)为1,则可能并不总是成立。有人可能已经关闭了stdin(0 ),然后再运行脚本(stderr也是如此)。

文件描述符继承的背景故事在PEP-446中。

我还添加了os.O_CREAT,因为我尝试重现您的问题的第一个失败是不存在kk.log。

不用说,除非尝试在os中使用接口(也许是一种练习),否则我认为您通常应该坚持subprocess本身。