shell 脚本中的 virtualenvwrapper 函数不可用
Posted
技术标签:
【中文标题】shell 脚本中的 virtualenvwrapper 函数不可用【英文标题】:virtualenvwrapper functions unavailable in shell scripts 【发布时间】: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!?
【问题讨论】:
【参考方案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以上是关于shell 脚本中的 virtualenvwrapper 函数不可用的主要内容,如果未能解决你的问题,请参考以下文章
shell脚本介绍 shell脚本结构和执行 date命令用法 shell脚本中的变量
20.1-4 shell脚本介绍 shell脚本结构和执行 date命令用法 shell脚本中的变量