【问题标题】:virtualenvwrapper functions unavailable in shell scriptsshell 脚本中的 virtualenvwrapper 函数不可用
【发布时间】:2011-11-24 05:10:11
【问题描述】:

所以,我再次制作了一个不错的 Python 程序,它让我的生活变得更加轻松,并节省了大量时间。当然,这涉及到一个virtualenv,它是用virtualenvwrapper 的mkvirtualenv 函数制作的。该项目有一个 requirements.txt 文件,其中包含一些必需的库(也有请求:D),如果没有这些库,程序将无法运行。

我正在尝试添加一个 bin/run-app 可执行 shell 脚本,该脚本将在我的路径中(实际上是符号链接)。现在,在这个脚本中,我需要切换到 virtualenv 才能运行这个程序。所以我把它放进去

#!/bin/bash
# cd into the project directory
workon "$(cat .venv)"
python main.py

文件 .venv 包含 virtualenv 名称。但是当我运行这个脚本时,我得到了workon: command not found 错误。

当然,我的 bashrc 中有 virtualenvwrapper.sh,但它似乎在这个 shell 脚本中不可用。

那么,我怎样才能在这里访问那些 virtualenvwrapper 函数呢?还是我这样做是错误的?你如何启动你的 python 工具,每个工具都有自己的 virtualenv!?

【问题讨论】:

    标签: python bash virtualenv virtualenvwrapper


    【解决方案1】:

    这是一个超级旧的线程,我遇到了类似的问题。出于好奇,我开始寻找更简单的解决方案。

    gnome-terminal --working-directory='/home/exact/path/here' --tab --title="API" -- bash -ci "workon aaapi && python manage.py runserver 8001; exec bash;"
    

    --workingdirectory 强制选项卡在默认情况下在引擎盖下打开,-ci 强制它像交互式界面一样工作,这解决了 venvwrapper 无法按预期运行的问题。

    您可以按顺序运行尽可能多的这些。它将打开选项卡,给它们一个别名,然后运行你想要的脚本。

    当我在终端中键入 startdev 时,我将一个别名放入我的 bashrc 中。

    我喜欢这个,因为它简单、易于复制、灵活,并且不需要摆弄变量等等。

    【讨论】:

      【解决方案2】:

      这是known issue。作为一种解决方法,您可以将脚本的内容设置为函数并将其放置在 ~/.bashrc~/.profile

      function run-app() {
        workon "$(cat .venv)"
        python main.py
      } 
      

      【讨论】:

        【解决方案3】:

        你也可以直接调用 virtualenv 的 python 可执行文件。首先找到可执行文件的路径:

        $ workon myenv
        $ which python
        /path/to/virtualenv/myenv/bin/python
        

        然后从你的 shell 脚本调用:

        #!/bin/bash
        
        /path/to/virtualenv/myenv/bin/python myscript.py
        

        【讨论】:

          【解决方案4】:

          将这些行添加到您的 .bashrc 或 .bash_profile

          export WORKON_HOME=~/Envs
          source /usr/local/bin/virtualenvwrapper.sh
          

          然后重新打开您的终端并尝试

          【讨论】:

            【解决方案5】:

            只需在脚本中获取virtualenvwrapper.sh 脚本即可导入virtualenvwrapper 的功能。然后您应该能够在脚本中使用workon 函数。

            也许更好的是,您可以创建一个 shell 脚本(例如,您可以将其命名为 venv-run.sh)以将任何 Python 脚本运行到给定的 virtualenv 中,并将其放置在 /usr/bin/usr/local/bin 或任何目录中在您的PATH 中。

            这样的脚本可能如下所示:

            #!/bin/sh
            # if virtualenvwrapper.sh is in your PATH (i.e. installed with pip)
            source `which virtualenvwrapper.sh`
            #source /path/to/virtualenvwrapper.sh # if it's not in your PATH
            workon $1
            python $2
            deactivate
            

            并且可以像venv-run.sh my_virtualenv /path/to/script.py一样简单地使用

            【讨论】:

            • 这需要硬编码 virtualenvwrapper.sh 脚本的位置,这取决于操作系统等。
            • @ShrikantSharat 好吧,因为这只是让您在 virtualenv 中运行脚本的一种更简单的方法(因此仅在您的系统上),这应该不是问题,不是吗?如果你想分发你的代码,我怀疑你会要求用户安装 virtualenv 并创建一个,你只需给他一个要安装的依赖项列表。
            • users 将是我的技术朋友,他们也希望为该程序的依赖项提供一个 virtualenv。我不必要求他们;)
            • @ShrikantSharat 如果 virtualenvwrapper.sh 在您的 PATH 中,则不需要对路径进行硬编码,例如,当它与 pip 一起安装时会发生这种情况(我相应地更新了我的答案)
            • @MatToufoutu 不幸的是,这里有一个假设。一些系统安装 virtualenvwrapper 更加“聪明”:将其放在/etc/bash_completion.d/virtualenvwrapper 中,它既不在路径上,也没有完全相同的名称:( 强制您在此类系统上的某个位置对其进行符号链接。
            【解决方案6】:

            我找不到在shell中触发virtualenvwrapper命令的方法。但是这个技巧可以帮助:假设你的环境。名称为myenv,然后在脚本开头添加以下行:

            ENV=myenv
            source $WORKON_HOME/$ENV/bin/activate
            

            【讨论】:

              【解决方案7】:

              显然,我这样做是错误的。与其将 virtualenv 的名称保存在 .venv 文件中,不如将其放在 virtualenv 的目录路径中。

              (cdvirtualenv && pwd) > .venv
              

              bin/run-app,我放了

              source "$(cat .venv)/bin/activate"
              python main.py
              

              耶!

              【讨论】:

                【解决方案8】:

                如果您的 Python 脚本需要特定的 virtualenv,则将其放置/安装到 virtualenv 的 bin 目录中。如果您需要在环境之外访问该脚本,那么您可以创建一个符号链接。

                来自 virtualenv 的 bin 的 main.py:

                #!/path/to/virtualenv/bin/python
                import yourmodule
                
                if __name__=="__main__":
                   yourmodule.main()
                

                PATH 中的符号链接:

                pymain -> /path/to/virtualenv/bin/main.py
                

                在 bin/run-app 中:

                #!/bin/sh
                # cd into the project directory
                pymain arg1 arg2 ...
                

                【讨论】:

                • 这行得通,但我不喜欢把 virtualenv 的 python 的路径放在 #!线,感觉有点脏。此外,创建 main.py inside virtualenv 的这一额外步骤使其不那么可移植。我的朋友不能只是克隆并从我那里运行它:)
                • @Shrikant Sharat:如果您编写简单的 setup.py,那么 pip install 会为您完成 shebang 和复制到 virtualenv/bin。您的朋友可以:pip install git+... 如果他们喜欢前沿技术。注意在这种情况下,main.py 被复制到 他们的 virtualenv 并且 shebang 被写入指向 他们的 virtualenv/python。
                • @Sebastian,从未考虑过该选项,但听起来不错。您推荐的任何好的文档阅读(除了我现在正在检查的 python 文档),如果有的话。谢谢!
                • @Shrikant Sharat:例如,guide.python-distribute.orgpip-installer.org
                猜你喜欢
                • 2012-10-18
                • 2012-06-05
                • 2014-06-18
                • 1970-01-01
                • 2023-02-11
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多