在 pyenv virtualenv 下运行的 python 脚本使用什么shebang
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/44076804/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
what shebang to use for python scripts run under a pyenv virtualenv
提问by xgord
When a python script is supposed to be run from a pyenv
virtualenv
what is the correct shebang for the file?
当 Python 脚本应该从pyenv
virtualenv
文件的正确shebang运行时?
As an example test case, the default python on my system (OSX) does not have pandas
installed. The pyenv virtualenv venv_name
does. I tried getting the path of the python executable from the virtualenv.
作为示例测试用例,我的系统 (OSX) 上的默认 python 尚未pandas
安装。pyenv virtualenvvenv_name
可以。我尝试从 virtualenv 获取 python 可执行文件的路径。
$ pyenv activate venv_name
(venv_name)$ which python
/Users/username/.pyenv/shims/python
So I made my example script.py
:
所以我做了我的例子script.py
:
#!/Users/username/.pyenv/shims/python
import pandas as pd
print 'success'
But when I tried running the script, I got an error:
但是当我尝试运行脚本时,出现错误:
(venv_name) $ ./script.py
./script.py: line 2: import: command not found
./script.py: line 3: print: command not found
Although running that path on the command line works fine:
尽管在命令行上运行该路径可以正常工作:
(venv_name) $ /Users/username/.pyenv/shims/python script.py
success
(venv_name) $ python script.py # also works
success
What is the proper shebang for this? Ideally, I want something generic so that it will point at the python of whatever my current venv is.
什么是合适的shebang?理想情况下,我想要一些通用的东西,以便它指向我当前的 venv 的 python。
回答by DSLima90
I don't really know why calling the interpreter with the full path wouldn't work for you, I use it all the time, but if you want to use the python interpreter that is in your environment you should do:
我真的不知道为什么用完整路径调用解释器对你不起作用,我一直在使用它,但是如果你想使用你环境中的 python 解释器,你应该这样做:
#!/usr/bin/env python
That way you search your environment for the python interpreter to use.
这样您就可以在您的环境中搜索要使用的 Python 解释器。
回答by ephemient
If you need to use more shell than you can put in the #!
shebang line, you can start the file with a simple shell script which launches Python on the same file.
如果您需要使用比#!
shebang 行多的 shell ,您可以使用一个简单的 shell 脚本启动该文件,该脚本在同一文件上启动 Python。
#!/bin/bash
"exec" "pyenv" "exec" "python" "#!/Users/username/.pyenv/python/versions/venv_name/bin/python
import pandas as pd
print 'success'
" "$@"
# the rest of your Python script can be written below
Because of the quoting, Python doesn't execute the first line, and instead joins the strings together for the module docstring... which effectively ignores it.
由于引用,Python 不会执行第一行,而是将字符串连接在一起作为模块 docstring ......这实际上忽略了它。
You can see more here.
你可以在这里看到更多。
回答by Dave X
As you expected, you should be able to use the full path to the virtual environment's python in the shebang to choose/control the environment the script runs in regardless of the environment of the controlling script.
如您所料,您应该能够在shebang 中使用虚拟环境python 的完整路径来选择/控制脚本运行的环境,而不管控制脚本的环境如何。
In the comments on your question, VPfB & you find that the /Users/username/.pyenv/shims/python
is a shell script that does an exec $pyenv_python
. You should be able to echo $pyenv_python
to determine the real python and use that as your shebang.
在对您的问题 VPfB 的评论中,您发现这/Users/username/.pyenv/shims/python
是一个执行exec $pyenv_python
. 您应该能够 echo $pyenv_python
确定真正的蟒蛇并将其用作您的shebang。
另见:https: //unix.stackexchange.com/questions/209646/how-to-activate-virtualenv-when-a-python-script-starts
Try pyenv virtualenvs
to find a list of virtual environment directories.
尝试pyenv virtualenvs
查找虚拟环境目录列表。
And then you might find a using shebang something like this:
然后你可能会发现使用 shebang 是这样的:
(venv_name) $ ./script.py
success
(venv_name) $ pyenv activate non_pandas_venv
(non_pandas_venv) $ ./script.py
success
(non_pandas_venv) $ . deactivate
$ ./script.py
success
$
... will enable the script to work using the chosen virtual environment in other (virtual or not) environments:
...将使脚本能够在其他(虚拟或非虚拟)环境中使用所选的虚拟环境工作:
sudo chmod +x script.py
The trick is that if you call out the virtual environment's python binary specifically, python looks around that binary's path location for the supporting files and ends up using the surrounding virtual environment. (See per How does virtualenv work?)
诀窍是,如果您专门调用虚拟环境的 python 二进制文件,python 会在该二进制文件的路径位置周围查找支持文件,并最终使用周围的虚拟环境。(参见每virtualenv 是如何工作的?)
回答by sadkeanu
maybe you need to check the file privileges:
也许您需要检查文件权限:
#!/bin/sh
#
# Choose the python we need. Explanation:
# a) '''\' translates to \ in shell, and starts a python multi-line string
# b) "" strings are treated as string concat by python, shell ignores them
# c) "true" command ignores its arguments
# c) exit before the ending ''' so the shell reads no further
# d) reset set docstrings to ignore the multiline comment code
#
"true" '''\'
PREFERRED_PYTHON=/Library/Frameworks/Python.framework/Versions/2.7/bin/python
ALTERNATIVE_PYTHON=/Library/Frameworks/Python.framework/Versions/3.6/bin/python3
FALLBACK_PYTHON=python3
if [ -x $PREFERRED_PYTHON ]; then
echo Using preferred python $ALTERNATIVE_PYTHON
exec $PREFERRED_PYTHON "##代码##" "$@"
elif [ -x $ALTERNATIVE_PYTHON ]; then
echo Using alternative python $ALTERNATIVE_PYTHON
exec $ALTERNATIVE_PYTHON "##代码##" "$@"
else
echo Using fallback python $FALLBACK_PYTHON
exec python3 "##代码##" "$@"
fi
exit 127
'''
__doc__ = """What this file does"""
print(__doc__)
import platform
print(platform.python_version())
回答by Neil McGill
It's not exactly answering the Q, but this suggestion by ephiement I think is a much better way to do what you want. I've elaborated a bit and added some more of an explanation as to how this works and how you can dynamically select the python to use:
它并没有完全回答 Q,但是我认为 ephiement 的这个建议是做你想做的更好的方法。我已经详细说明并添加了更多关于它是如何工作的以及如何动态选择要使用的python的解释:
##代码##