Python 使用subprocess.call()运行bin/buildout失败

Python 使用subprocess.call()运行bin/buildout失败,python,buildout,Python,Buildout,tl,dr:我有一些构建可以很好地与shell中的“bin/buildout”配合使用,但是当我从Python中运行subprocess.call([“bin/buildout”])或类似的调用时失败。为什么?有解决办法吗 我添加了“python”标记,而不仅仅是“buildout”,因为这可能是从shell调用python脚本与使用subprocess.call()或os.system()从python调用python脚本的细微差别。我不知道为什么他们会不同。但这可能是一个构建,因为构建会重写

tl,dr:我有一些构建可以很好地与shell中的“bin/buildout”配合使用,但是当我从Python中运行subprocess.call([“bin/buildout”])或类似的调用时失败。为什么?有解决办法吗

我添加了“python”标记,而不仅仅是“buildout”,因为这可能是从shell调用python脚本与使用subprocess.call()或os.system()从python调用python脚本的细微差别。我不知道为什么他们会不同。但这可能是一个构建,因为构建会重写自身,然后重新启动自身

为了构建我想展示的示例,我从一个新的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()
#!/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之后,它将获得“distribute”,重写bin/buildout,并重新启动自身。因此,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()
#!/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

如您所见,它正试图安装到该用户无权访问的system dist软件包中。但是为什么呢?从shell运行相同的脚本有什么区别?

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

从:

如果shell为True,则指定的命令将通过 壳如果您主要是将Python用于 它在大多数系统外壳上提供了增强的控制流,并且仍然需要 方便访问其他外壳功能,如外壳管道, 文件名通配符、环境变量扩展和~ 到用户的主目录


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


希望有帮助。:)

然后设置
shell=True
,它将使用默认的shell。@MartijnPieters不,在Windows以外的任何情况下执行
subprocess.call(shell\u code,shell=True)
与只传递
subprocess.call(['/bin/sh','-c',shell\u code])
相同。它没有为您的用户使用默认的登录shell;所以
distribute
安装需要
bash
。这就解决了它!我很想理解为什么,但现在让它工作起来很好:-)我尝试了这个(subprocess.call([“bin/buildout”],shell=True)),但没有帮助。同样的错误。