python check_output失败,退出状态为1,但Popen适用于同一命令

Dee*_*pak 5 python subprocess popen

命令框架以识别Xcode是否在Mac上运行: cmd = "ps -ax | grep -v grep | grep Xcode"

如果Xcode没有运行,那么上面的命令适用Popen于subprocess模块的方法,但是提出了一个CalledProcessErrorwith check_output方法.我试图stderr通过以下代码检查,但未能获得适当的信息来理解原因.

from subprocess import check_output, STDOUT, CalledProcessError

psCmd = "ps -ax | grep -v grep | grep Xcode"
o = None
try:
    o = check_output(psCmd, stderr=STDOUT, shell=True)
except CalledProcessError as ex:
    print 'Error:', ex, o
Run Code Online (Sandbox Code Playgroud)

异常消息如下:

Error: Command 'ps -ax | grep -v grep | grep Xcode' returned non-zero exit status 1 None

问题:为什么上面的命令适用于Popen,但是check_output失败了?

注意:如果Xcode正在运行,则命令适用于这两种方法.

jfs*_*jfs 19

check_output()按预期工作.以下是它的简化实现Popen():

def check_output(cmd):
    process = Popen(cmd, stdout=PIPE)
    output = process.communicate()[0]
    if process.returncode != 0:
        raise CalledProcessError(process.returncode, cmd, output=output)
    return output
Run Code Online (Sandbox Code Playgroud)

grep1如果它没有找到任何东西则返回,即,如果Xcode没有运行,你应该期望异常.

注意:正如实现所示,即使发生异常,您也可以获得输出:

#!/usr/bin/env python
from subprocess import check_output, STDOUT, CalledProcessError

cmd = "ps -ax | grep -v grep | grep Xcode"
try:
    o = check_output(cmd, stderr=STDOUT, shell=True)
    returncode = 0
except CalledProcessError as ex:
    o = ex.output
    returncode = ex.returncode
    if returncode != 1: # some other error happened
        raise
Run Code Online (Sandbox Code Playgroud)

您可以使用pgrep -a Xcode命令代替(注意:以...开头p)或使用psutil模块作为可移植代码:

#!/usr/bin/env python
import psutil # $ pip install psutil

print([p.as_dict() for p in psutil.process_iter() if 'Xcode' in p.name()])
Run Code Online (Sandbox Code Playgroud)

  • `returncode`在try/except中设置为1.为了表明如果`check_output()`没有引发异常,它总是为零.两个分支(有和没有异常)都设置了两个变量:你可以无论Xcode是否正在运行,都要在代码后面使用`o`和`returncode`. (2认同)