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 运行相同的脚本有什么区别?