子进程模块无法运行命令 [英] Subprocess module fails to run command

查看:31
本文介绍了子进程模块无法运行命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试对我的一组文件执行 Google 的 cpplint.py,并将结果收集到一个日志文件中.但是,我还没有设法击败 subprocess 模块.我当前的代码在这里:

I'm trying to execute Google's cpplint.py on a group of my files and collect the results to one log file. However, I have not managed to beat the subprocess module. My current code is here:

import os, subprocess

rootdir = "C:/users/me/Documents/dev/"
srcdir = "project/src/"

with open(rootdir+srcdir+"log.txt", mode='w', encoding='utf-8') as logfile:
    for subdir, dirs, files in os.walk(rootdir+srcdir):
        for file in files:
            if file.endswith(".h") or file.endswith(".cpp"):
                filewithpath=os.path.join(subdir, file)
                cmd=['c:/Python27/python.exe','C:/users/me/Documents/dev/cpplint.py','--filter=-whitespace,-legal,-build/include,-build/header_guard/', filewithpath]               
                output = subprocess.check_output(cmd)
                logfile.write(output.decode('ascii'))

尝试运行上面的代码会抛出一个错误:

Trying to run the above code throws an error:

  File "C:\Python32\lib\site.py", line 159
    file=sys.stderr)
        ^ SyntaxError: invalid syntax Traceback (most recent call last):   File "C:\Users\me\Documents\dev\project\src\verifier.py", line 19, in <module>
    output = subprocess.check_output(cmd)   File "C:\Python32\lib\subprocess.py", line 511, in check_output
    raise CalledProcessError(retcode, cmd, output=output) subprocess.CalledProcessError: Command '['c:/Python27/python.exe', 'C:/users/me/Documents/dev/cpplint.py', '--filter=-whitespace,-legal,-build/include,-build/header_guard/', 'C:/users/me/Documents/dev/project/src/aboutdialog.cpp']' returned non-zero exit status 1

如果我用更简单的东西代替cmd:

If I substitute the cmd with something simpler like:

cmd=['C:/WinAVR-20100110/bin/avr-gcc.exe','--version']

然后脚本按预期工作.

我也尝试过使用单个命令字符串而不是字符串列表作为 cmd,但结果是一样的.在调试代码时,我从调试器中复制了 list-of-strings-turned-into-the-command-line-command 并在 Windows 命令行中运行它,该命令按预期运行.

I have also tried to use a single command string instead of a list of strings as cmd, but the result is the same. When debugging the code, I copied the list-of-strings-turned-into-the-command-line-command from the debugger and ran it in the Windows command line, and the command ran as expected.

运行我的脚本的 Python 解释器是 Python 3.2.非常感谢任何提示.

The Python interpreter running my script is Python 3.2. Any tips are greatly appreciated.

推荐答案

看起来 cpplint.py 只是以非零返回码退出 - 例如,如果它在它检查的源文件中发现错误或lint".

Looks like cpplint.py is simply exiting with a non-zero return code - which it might do, for instance, if it finds errors or "lint" in the source files it is checking.

请参阅 subprocess.check_output 的文档.请注意,如果执行的命令返回 非零退出代码,则会引发 subprocess.CalledProcessError.

See the documentation for subprocess.check_output. Note that if the command executed returns a non-zero exit code then a subprocess.CalledProcessError is raised.

你可以通过观察CalledProcessError来解决它,例如

You could work around it by watching for CalledProcessError, e.g.

try:
    output = subprocess.check_output(cmd)
except subprocess.CalledProcessError as e:
    # ack!  cpplint.py failed... report an error to the user?

编辑:

SyntaxError 似乎是这里的关键,并且可能是由 C:\Python32\lib 在您的 PYTHONPATH 中引起的(明确地,或者,这可能发生如果它是您当前的工作目录).

The SyntaxError seems to be the key here, and is probably caused by C:\Python32\lib being in your PYTHONPATH (either explicitly, or, this could happen if it is your current working directory).

Python 解释器(大约从 1.5.2-ish 开始)在启动时自动运行 import site.因此,在这种情况下,您的脚本将开始执行:

The Python interpreter (since about 1.5.2-ish) automatically runs import site when started. So, when this is the case, and your script goes to execute:

c:/Python27/python.exe C:/users/me/Documents/dev/cpplint.py ...

然后 Python 2.7 解释器将首先找到 C:\Python32\lib\site.py,并尝试加载它,而不是(大概)在C:\Python27\lib\site.py.问题是 Python 3 的 site.py 包含与 Python 2 不兼容的语法,因此 subprocess.check_output 启动的进程在它有机会之前失败并出现 SyntaxError运行 cpplint,它会传播 CalledProcessError.

then the Python 2.7 interpreter will find C:\Python32\lib\site.py first, and try to load that, instead of the one (presumably) at C:\Python27\lib\site.py. The issue is that Python 3's site.py contains syntax incompatible with Python 2, so the process launched by subprocess.check_output is failing with a SyntaxError before it even gets a chance to run cpplint, which propagates the CalledProcessError.

解决方案?确保 Python2 获得真正的 Python2PYTHONPATH",对于 Python3 也是如此!换句话说,在运行 Python2 解释器时,确保 C:\Python32\lib 不在 PYTHONPATH 搜索路径中.

Solution? Make sure Python2 gets a bonafide Python2 "PYTHONPATH", and likewise for Python3! In other words, make sure C:\Python32\lib is not in the PYTHONPATH search path when running the Python2 interpreter.

在您的情况下执行此操作的一种方法是在启动进程时设置显式环境,例如:

One way to do this in your case is to set an explicit environment when launching the process, e.g.:

python2_env = {"PYTHONPATH": "path/to/python2/stuff:..."}
output = subprocess.check_output(cmd, env=python2_env)

这篇关于子进程模块无法运行命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆