3

tl,dr:我的构建可以在 shell 中使用“bin/buildout”正常工作,但是当我从 Python 运行 subprocess.call(["bin/buildout"]) 或类似内容时失败。为什么?任何解决方法?

我添加了“python”标签而不仅仅是“buildout”,因为这可能是从 shell 调用 python 脚本与使用 subprocess.call() 或 os.system() 从 python 调用的细微差别。我不知道为什么他们会有所不同。不过,这可能是 Buildout 的事情,因为 Buildout 会自行重写,然后重新启动。

为了构建我想要展示的示例,我从一个新的 Ubuntu 12.04 LTS 虚拟机开始。然后我在上面安装 git (sudo apt-get install git) 并克隆我们的一个存储库,其中几乎没有任何内容:

git clone git://github.com/lizardsystem/lizard-datasourceviewer.git

然后我 cd 进入它并运行 bootstrap.py:

cd lizard-datasourceviewer
python bootstrap.py

到现在为止还挺好。现在可以运行“bin/buildout”,它会毫无问题地运行(嗯,在某些时候它会出错,因为系统没有 matplotlib——这是预期的结果)。但是不要那样做,因为一旦你这样做了,下面的错误就不会发生了。如果您这样做了,请删除该目录并再次克隆它。

如果代替我从 Python 运行它,例如:

$ python
>>> import subprocess
>>> subprocess.call(["bin/buildout"])

然后这会更早地失败(有关错误,请参见下文)。这是一个问题,因为我们想从脚本中调用 buildout。子进程调用的变体,如 os.system("bin/buildout") 或 subprocess.call(["/bin/sh", "-c", "bin/buildout"]) 没有帮助。一旦 bin/buildout 从命令行运行一次,问题就消失了,即使再次调用 bootstrap.py 也是如此。

我知道什么时候会出错。最初,bin/buildout 看起来像这样:

#!/usr/bin/python

import sys
sys.path[0:0] = [
  '/usr/lib/python2.7/dist-packages',
  '/usr/lib/python2.7/dist-packages',
  '/usr/lib/python2.7/dist-packages',
  '/usr/lib/python2.7/dist-packages',
  '/usr/lib/python2.7/dist-packages',
  '/usr/lib/python2.7/dist-packages',
  '/usr/lib/python2.7/dist-packages',
  '/usr/lib/python2.7/dist-packages',
  '/usr/lib/python2.7/dist-packages',
  '/usr/lib/python2.7/dist-packages',
  '/usr/lib/python2.7/dist-packages',
  '/home/vagrant/lizard-datasourceviewer/eggs/zc.buildout-1.4.4-py2.7.egg',
  ]

import zc.buildout.buildout

if __name__ == '__main__':
    zc.buildout.buildout.main()

从命令行运行 bin/buildout 后,它会“分发”,重写 bin/buildout,然后重新启动。结果 bin/buildout 看起来像这样:

#!/usr/bin/python

import sys
sys.path[0:0] = [
  '/home/vagrant/lizard-datasourceviewer/eggs/zc.buildout-1.4.4-py2.7.egg',
  '/home/vagrant/lizard-datasourceviewer/eggs/distribute-0.6.27-py2.7.egg',
  ]

import zc.buildout.buildout

if __name__ == '__main__':
    zc.buildout.buildout.main()

当 bin/buildout 从 Python 而不是从 shell 运行时,正是这个重写和重新启动步骤似乎失败了。错误信息是:

vagrant@precise64:~/lizard-datasourceviewer$ python
Python 2.7.3 (default, Apr 20 2012, 22:39:59) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> subprocess.call(["bin/buildout"])
Getting distribution for 'mr.developer==1.21'.
Got mr.developer 1.21.
Getting distribution for 'buildout-versions==1.5'.
Got buildout-versions 1.5.
mr.developer: Creating missing sources dir /home/vagrant/lizard-datasourceviewer/src.
Getting distribution for 'distribute==0.6.27'.
Before install bootstrap.
Scanning installed packages
Setuptools installation detected at /usr/lib/python2.7/dist-packages
Non-egg installation
Removing elements out of the way...
Already patched.
/usr/lib/python2.7/dist-packages/setuptools.egg-info already patched.
After install bootstrap.
Don't have permissions to write /usr/local/lib/python2.7/dist-packages/setuptools-0.6c11-py2.7.egg-info, skipping
Creating /usr/local/lib/python2.7/dist-packages/setuptools-0.6c11-py2.7.egg-info
**error: /usr/local/lib/python2.7/dist-packages/setuptools-0.6c11-py2.7.egg-info: Permission denied**
An error occured when trying to install distribute 0.6.27. Look above this message for any errors that were output by easy_install.
While:
  Installing.
  Checking for upgrades.
  Getting distribution for 'distribute==0.6.27'.
Error: Couldn't install: distribute 0.6.27
1

如您所见,它正在尝试安装到该用户无权访问的系统 dist-packages 中。但为什么?从 shell 运行相同的脚本有什么区别?

4

2 回答 2

2

不知道为什么,但使用subprocess.call(['/bin/bash', '-c', 'bin/buildout'])似乎为我解决了它,subprocess.call(['/bin/sh', '-c', 'bin/buildout'])失败了。Ubuntu 12.04。

希望能帮助到你。:)

于 2012-12-20T23:51:52.393 回答
0

尝试subprocess.call()使用可选参数调用shell=True

子流程文档

如果 shell 为 True,指定的命令将通过 shell 执行。如果您将 Python 主要用于它在大多数系统 shell 上提供的增强控制流,并且仍然希望方便地访问其他 shell 功能,例如 shell 管道、文件名通配符、环境变量扩展和 ~ 到用户家的扩展,这将很有用目录。

于 2012-12-20T22:40:07.657 回答