1

我尝试在安装过程中使用自定义安装从 setup.py 调用 Python 脚本:

class CustomInstall(install):
    def run(self):
        install.run(self)

        ...

        p = subprocess.Popen(
            [sys.executable, 'demo_package/deploy_database.py'],
            shell=True,
            stdout=subprocess.PIPE,
            cwd=os.path.join(self.install_lib, 'demo_package'))

        out, err = p.communicate()

setup(..., cmdclass=dict(install=CustomInstall))

在 Ubuntu 机器上部署包时,该过程不会执行 deploy_database.py,而是显示任何内容。当我使用 Ctrl+C 手动停止它时,输出似乎表明它没有实际运行 deploy_database.py,而是简单地启动 Python:

^CDownloading/unpacking PypiPackagesMonitoring
  Downloading demo-1.0.64.zip  
  Running setup.py egg_info for package demo

Installing collected packages: demo
  Running setup.py install for demo

    Python 3.3.2+ (default, Oct  9 2013, 14:50:09)
    [GCC 4.8.1 on linux
    Type "help", "copyright", "credits" or "license" for more information.
Cleaning up...
Operation cancelled by the user
Storing complete log in /home/.../.pip/pip.log

我调用 Python 脚本的方式有什么问题?我应该怎么做呢?

4

1 回答 1

1

shell=True不需要[sys.executable, 'demo_package/deploy_database.py'],并且会导致问题。你这样做的方式(如果你省略shell=True)是首选方式,因为它绕过了外壳。

shell=True使 Popen 将传递的命令移交给 shell(例如/bin/bash,取决于为当前用户配置的 shell)。仅执行列表中传递的第一个命令,列表的其他元素作为参数传递给 shell 本身(来自docs):

在 Unix 上 shell=True […] 如果 args 是一个序列,第一项指定命令字符串,任何附加项将被视为 shell 本身的附加参数。

shell=True有点危险,但在某些情况下也很有用。有关详细信息,请参阅文档

于 2013-10-30T19:13:39.603 回答