2015-02-23 104 views
4

命令框架,以确定是否Xcode是在Mac上运行:cmd = "ps -ax | grep -v grep | grep Xcode"蟒蛇check_output失败,退出状态1,但POPEN适用于相同的命令

如果Xcode中没有运行,那么上面的命令与subprocess模块的Popen方法效果很好,但用check_output方法提出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 

异常信息如下:

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

问:为什么POPEN上面的命令工作,但失败check_output?

注意:如果Xcode正在运行,Command与两种方法都能很好地协作。

+0

无论如何,你在Python本身执行'grep'处理要好得多。 – tripleee 2015-02-23 14:58:18

+0

即使我在python中处理输出,我也必须使用'subprocess'模块。所以我认为这是在'bash'结束所有工作的好方法。 – Deepak 2015-02-23 15:18:22

+0

相关:[在Python中通过名称杀死进程](http://stackoverflow.com/q/2940858/4279) – jfs 2015-02-24 07:12:50

回答

16

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()]) 
+0

我现在明白了,为什么check_output表现为行为。检查返回代码是否很酷。我会用你的想法与errno。一些**怀疑**:_1._为什么我们必须在值为0的'try'块中初始化'returncode'?_2_。我们不能比较'ex.returncode'直接在'if'条件下的值为1吗?它是否有助于某些目的,我还没有明白。 – Deepak 2015-02-25 07:58:58

+2

're turncode'设置在try /里,除非为了让你知道check_output()没有引发异常,它总是为零2.两个分支(有和没有例外)设置两个变量:你可以使用代码后的'o'和'returncode',而不管Xcode是否在运行。 – jfs 2015-02-25 08:02:07

2

从Python文档:“如果返回代码是非零它引发一个CalledProcessError。”。这就是Xcode不运行时发生的事情;由于grep找不到您要查找的字符串Xcode,因此最终的grep Xcode以非零状态退出。因此,check_output()将引发异常。我发现这个the Python subprocess documentation

+0

我不这么认为。如果我在没有启动Xcode的终端中运行此命令并检查errno变量,它仍然保持值0.要检查errno,我使用了echo“$?”。 – Deepak 2015-02-23 14:43:24

+1

嗯...当我尝试'ps -aef | grep -v grep | grep Xcode; echo $?',我得到输出:'1' – 2015-02-23 14:53:33

+0

@DeepakrajHR你的意思是即使Xcode没有启动你的grep命令找到它了吗?您显示错误消息'错误:命令'ps -ax | grep -v grep | grep Xcode返回的非零退出状态1 None'是你的python脚本的输出,因为你已经在你的代码中处理了异常 – 2015-02-23 14:55:08

1

如果你的grep命令grep Xcode返回任何结果,那么该命令的returncode将是非零的,这就是为什么check_output呼吁CalledProcessError,这是你在print命令的输出所看到的

要获得你的命令的输出是它下面的代码错误或成功使用: - 如果它的返回码0否则它会调用异常

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

psCmd = "ps -aef | grep -v grep | grep Xcode" 
o = None 
o = check_output(psCmd+";exit 0", stderr=STDOUT, shell=True) 

check_output只会显示你的命令的输出。

+0

请参阅我对Karel Kubat的回答的评论 – Deepak 2015-02-23 14:46:01

+0

这是一个不错的想法,如[link](https://docs.python.org/2/library/subprocess.html#subprocess.check_output)所示。但是,为什么我从Python脚本得到的错误代码是1,终端是0。无论如何,现在我正在使用Popen来解决问题。但是问题仍然存在:-( – Deepak 2015-02-23 15:09:09

+0

我得到了我的答案,现在我正在使用这种方式,但现在我想知道,如果命令因其他未知原因而失败会怎么样,我认为这也会因为退出而绕过0'。是否有办法来捕捉这些例外 – Deepak 2015-02-23 15:24:56

0

check_output的目的是确保您运行的命令成功完成。如果grep Xcode没有成功,假设失败。

无论如何,在Python中进行搜索时,你想要的会更简单。

output = check_output(['ps', '-ax'], shell=False) 
if 'Xcode' in output: 
    print('Xcode appears to be running') 

这个拥有它实际上失败,如果ps由于某种原因失败外壳版本的附加(很轻微的)好处。当它不在管道末端时,shell将简单地忽略ps的退出代码。

相关问题