2014-01-10 106 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

相關問題