指定框架以确定Xcode是否在Mac上运行:cmd = "ps -ax | grep -v grep | grep Xcode"
如果Xcode未运行,则上述命令适用于Popen
模块的subprocess
方法,但使用CalledProcessError
方法引发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
异常消息如下:
Error: Command 'ps -ax | grep -v grep | grep Xcode' returned non-zero exit status 1 None
问题:为什么上面的命令适用于Popen,但是使用check_output失败了?
注意:如果Xcode正在运行,命令适用于这两种方法。
答案 0 :(得分:18)
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()])
答案 1 :(得分:2)
从Python文档:“如果返回代码非零,则会引发CalledProcessError。”这就是当Xcode没有运行时你会发生什么;最终grep Xcode
退出时状态为非零,因为grep
无法找到您要查找的字符串Xcode
。因此,check_output()
将引发异常。
顺便说一句,我在the Python subprocess documentation上找到了这个。
答案 2 :(得分:1)
如果你的grep命令grep Xcode
没有返回任何结果,那么命令的returncode
将不为零,这就是为什么check_output
正在调用CalledProcessError
,这就是你正在print
命令
要获得命令的输出,请将错误或成功使用以下代码: -
#!/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
,否则它会调用异常。
答案 3 :(得分: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
的退出代码不在管道的末尾,它就会忽略它。