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

标签 python subprocess popen

确定 Xcode 是否在 Mac 上运行的命令:cmd = "ps -ax | grep -v grep | grep Xcode"

如果 Xcode 未运行,则上述命令与 subprocess 模块的 Popen 方法配合使用效果很好,但会引发 CalledProcessError检查输出 方法。我试图通过以下代码检查 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

异常信息如下:

错误:命令 'ps -ax | grep -v grep | grep Xcode' 返回非零退出状态 1 无

问题:为什么上述命令对 Popen 有效,但对 check_output 无效?

注意:如果 Xcode 正在运行,命令对这两种方法都适用。

最佳答案

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

grep 如果未找到任何内容,则返回 1,即,如果 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

您可以使用 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()])

关于python check_output 失败,退出状态为 1,但 Popen 适用于相同的命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28675138/

相关文章:

python - 在 Keras 中舍入激活函数

python - 默认情况下,Spyder 使用 Spyder Python 2.7 打开,而我的 Anaconda 安装在 Python 3.6+

python - 使用 stdin/stdout 通过 Python 子进程与 smbpasswd 通信

c - popen 在进程之间传递二进制数据

python - wxPython 类型错误 : String or Unicode type required error

python - 在 SQLAlchemy 模型中存储 pandas DataFrame

go - 在 Golang 中将字符串通过管道传输到命令的 STDIN

python - 如何将错误消息从 shell 脚本传递到 Python 脚本?

c - 为什么 pclose(3) 不等待 shell 命令终止

c - 在 Windows 上将命令通过管道传输到缓冲区