2014-01-10 62 views
0

我必须通过python脚本运行“提交”命令并根据其退出或返回状态打印消息。如何使用python中的子进程获取退出状态?

代码如下:

import subprocess 

msg = 'summary about commit' 
commitCommand = 'hg commit -m "{}"'.format(msg) 

p = subprocess.Popen(commitCommand, stdout=subprocess.PIPE) 
output = p.communicate()[0] 

if p.returncode: 
    print 'commit failed' 
    sys.exit() 
else: 
    print 'Commit done' 

这是给我以下错误:

Traceback (most recent call last): 
    File "script.py", line 66, in <module> 
    p = subprocess.Popen(commitCommand, stdout=subprocess.PIPE) 
    File "/usr/lib/python2.7/subprocess.py", line 711, in __init__ 
    errread, errwrite) 
    File "/usr/lib/python2.7/subprocess.py", line 1308, in _execute_child 
    raise child_exception 
OSError: [Errno 2] No such file or directory 

如何纠正这个错误?

+2

'进口shlex; ...; subprocess.Popen(shlex.split(commitCommand),...)'。 [相关问题](http://stackoverflow.com/q/21029154/510937),['Popen']的文档(http://docs.python.org/2/library/subprocess.html#subprocess.Popen) (你应该阅读)。 – Bakuriu

+0

@Bakuriu:为什么在OP构建字符串时使用'shlex.split()'? –

回答

0

您没有使用shell=True,在这种情况下,你需要在命令传递及其参数preparsed,作为一个列表:

commitCommand = ['hg', 'commit', '-m', msg] 

这也意味着你不不需要引用这个信息;这只在使用shell时需要,并且您希望将整个消息作为一个参数传递。

0

来自文档;

args should be a sequence of program arguments or else a single string. By default, the program to execute is the first item in args if args is a sequence. If args is a string, the interpretation is platform-dependent and described below. See the shell and executable arguments for additional differences from the default behavior. Unless otherwise stated, it is recommended to pass args as a sequence.

On Unix, if args is a string, the string is interpreted as the name or path of the program to execute. However, this can only be done if not passing arguments to the program.

所以,它在寻找一个文件hg commit -m "{}".format(msg)。 Popen想要一个列表,第一个元素是“hg”,或者更好,是一个真正的路径。

或者设置SHELL =在POPEN 真(这一切都从文档,而不是故作实际测试这个非常频繁) 并获得Popen(['/bin/sh', '-c', args[0], args[1], ...])效果。

Bakuriu的评论建议是一个很好的安全赌注,但使用shlex。

0

前述方法更安全使用......但或者会有肮脏的方式做任何事情...

而不是分裂的命令放到一个字符串数组...你也可以使用shell=Truestdout = subprocess.PIPE.

一起,但是这是蟒蛇说,关于如果不使用shell =真和一个字符串,给出一个命令使用shell = True.

Warning Passing shell=True can be a security hazard if combined with untrusted input. See the warning under Frequently Used Arguments for details. 

,它抛出上述ERR或者你得到了,因为它查找的第一个命令是shell路径,并且你传递了不存在的hg
明智地使用shell = True

P.S.要知道,你已经被警告:P

相关问题