【问题标题】:How to get exit status using subprocess in python?如何在python中使用子进程获取退出状态?
【发布时间】:2014-01-29 03:49:27
【问题描述】:

我必须通过 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

如何纠正这个错误?

【问题讨论】:

  • import shlex; ...;subprocess.Popen(shlex.split(commitCommand), ...)Related questionPopen 的文档(您应该阅读)。
  • @Bakuriu:当 OP 正在 构建字符串 时,为什么要使用 shlex.split()

标签: python python-2.7


【解决方案1】:

来自文档;

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。

【讨论】:

    【解决方案2】:

    上述过程使用起来更安全......但是做任何事情都会有肮脏的方式......

    除了将命令拆分为字符串数组...您还可以使用 shell=Truestdout = 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

    【讨论】:

      【解决方案3】:

      您没有使用shell=True,在这种情况下,您需要将命令及其预先解析的参数作为列表传递:

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

      这也意味着您不需要引用消息;这仅在使用 shell 并且您想将整个消息作为一个参数传递时才需要。

      【讨论】:

        猜你喜欢
        • 2020-02-27
        • 1970-01-01
        • 1970-01-01
        • 2018-06-24
        • 1970-01-01
        • 1970-01-01
        • 2015-02-03
        • 2014-11-01
        • 1970-01-01
        相关资源
        最近更新 更多