【问题标题】:Running python script from inside virtualenv bin is not working从 virtualenv bin 内部运行 python 脚本不起作用
【发布时间】:2012-08-11 09:03:25
【问题描述】:

我有一个脚本希望在全球范围内可用。我从标准的 hashbang 开始:

#! /usr/bin/env python

并将其链接到我的 virtualenv 的 bin 目录中:

~/environments/project/env/bin/myscript

并将该目录添加到我的路径中。当我运行命令时:

myscript

我收到其中一个库的导入错误。但是,如果我激活虚拟环境并运行脚本,它会按预期工作。

我已经排除了符号链接的问题(我也尝试将脚本移动到 bin 文件夹中)。我也试过用 python 运行脚本

python ~/environments/project/env/bin/myscript

以前我使用的是激活环境然后运行我的脚本的脚本,但我的印象是从这个文件夹运行的脚本应该与 virtualenv 的解释器和站点包一起运行。关于为什么这可能不起作用的任何想法或我可以调试它的一些方法?

【问题讨论】:

  • 与您的问题无关:尽管大多数 shell 忽略它,但使用 #! / 严格来说是错误的,因为必须将空间视为程序路径的一部分。放下空间,你就安全了。

标签: python virtualenv rundeck


【解决方案1】:

将脚本放入您的 virtualenv 的 bin 中,然后将该 bin 位置添加到您的全局 PATH 将不会自动获取您的 virtualenv。您确实需要先获取它以使其处于活动状态。

您的系统所知道的就是检查可执行文件的额外路径并运行它。该脚本中没有任何指示虚拟环境的内容。

但是,您可以将 she-bang 行硬编码到您的 virtualenv python,在这种情况下,站点包将最终出现在路径上:

#!/Users/foo/environments/project/env/bin/python

或者另一种选择是简单地创建一个小型 bash 包装器来调用您的原始 python 脚本,这将允许您使用通用的 she-bang 离开您的原始脚本..

所以如果 myscript.py 是:#!/usr/bin/env python ...

那你就可以发myscript了:

#!/bin/bash

/Users/foo/environments/project/env/bin/python myscript.py

当您执行myscript 时,它会使用您设置的解释器显式调用您的python 脚本。

【讨论】:

  • 谢谢我原来的脚本就是这样做的。我记得看到一些我认为文件夹会激活环境的东西,但你说得对,我认为那是不可能的。
  • 难道你不需要获取 myscript 的源代码,而不是简单地通过名称调用它吗?
  • @JoshUsre 不,在这种情况下,myscript 是以特定方式启动 myscript.py 的引导程序。当您希望在当前 shell 中评估脚本的效果时,您可以执行源脚本。
【解决方案2】:

我认为您对 virtualenv 的工作原理感到困惑。

简而言之,virtualenv 会修改您的 shell 环境,以便 Python 在不同的区域中查找您要导入的模块。存储虚拟环境的位置与存储在 virtualenv 中运行的源文件的位置之间确实没有任何关系。如果您愿意,您可以将您的 virtualenv 存储在一个名为 ~/environments/my_env 的目录中,并将您在使用 virtualenv 时编写的所有源代码存储在 ~/projects/my_proj 中。

您可以在文档中阅读有关 what virtulenv does 的更多信息。

真的,唯一告诉 python 在哪里可以找到模块的东西完全基于 python(see the docs 它是如何工作的)。激活 virtualenv 会改变 python 的工作方式。

您可以返回让 shell 脚本为您激活 virtualenv,或者您可以关注 this recipe 直接从您的脚本中激活它。

activate_this = '/path/to/env/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))

如果您选择此路线,请牢记文档提供的信息:

这会改变 sys.path 甚至改变 sys.prefix,但也允许 您使用现有的口译员。您环境中的项目将 首先出现在 sys.path 上,在全局项目之前。但是,全球项目 将始终可访问(就好像 --system-site-packages 标志有 被用于创造环境,不管它是不是)。还, 这无法撤消其他环境或模块的激活 已导入。例如,您不应该尝试激活 Web请求之前的环境;你应该激活一个环境 尽早,不要在那个过程中再做一次。

【讨论】:

    【解决方案3】:

    你不能只添加一个相对路径吗?这对我有用:

    #!./env/bin/python
    

    【讨论】:

      【解决方案4】:

      我遇到了同样的问题并想出了这个解决方案:https://github.com/jabbalaci/wpython。这是一个名为“wpython”的脚本,它使用 venv 中的本地 Python 解释器调用您的程序。因此,代替“/Users/foo/environments/project/env/bin/python myscript.py”,写“wpython /path/to/myscript.py”就足够了。启动器脚本可能如下所示:

      #!/usr/bin/env bash
      
      cd /the/directory/where/myscript.py/is/located
      wpython myscript.py
      

      【讨论】:

        【解决方案5】:

        如果您使用的是 windows,您可以在 python 文件的顶部包含以下行。

        #! P:\Workspace\pythontut\Scripts python
        

        【讨论】:

          猜你喜欢
          • 2013-07-19
          • 1970-01-01
          • 2018-02-15
          • 2021-07-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-03-07
          • 2013-09-18
          相关资源
          最近更新 更多