我必须通过python脚本运行“commit”命令,并根据其退出或返回状态打印一条消息。
代码如下:
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
如何更正此错误?
答案 0 :(得分:0)
来自文档;
args应该是一系列程序参数或者是一个单独的字符串。默认情况下,如果args是序列,则要执行的程序是args中的第一项。如果args是一个字符串,则解释与平台有关,如下所述。有关与默认行为的其他差异,请参阅shell和可执行参数。除非另有说明,否则建议将args作为序列传递。
在Unix上,如果args是一个字符串,则该字符串被解释为要执行的程序的名称或路径。但是,只有在不将参数传递给程序时才能执行此操作。
因此,它正在寻找文件hg commit -m "{}"
和.format(msg)
。 Popen想要一个列表,第一个元素是“hg”,或者更好,一个真正的路径。
或者在Popen 中设置shell = True(这全部来自文档,而不是假装经常对此进行实际测试)
并获得Popen(['/bin/sh', '-c', args[0], args[1], ...])
效果。
Bakuriu的评论建议是一个不错的安全赌注,但使用shlex。
答案 1 :(得分:0)
上述过程使用起来更安全......但是也可能有肮脏的方法做任何事情......
您可以将shell=True
与stdout = subprocess.PIPE.
但这就是python关于使用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.
如果你没有使用shell = True并在字符串中给出一个命令,它会抛出你得到的上述错误,因为它查找的第一个命令是shell路径,而你传递的hg
是不存在的。
但明智地使用shell = True
。
P.S。请注意,您已收到警告:P
答案 2 :(得分:0)
您没有使用shell=True
,在这种情况下,您需要传递命令及其参数,并将其作为列表传递:
commitCommand = ['hg', 'commit', '-m', msg]
这也意味着您不需要引用消息;只有在使用shell时才需要,并且您希望将整个消息作为一个参数传递。