![](/img/trans.png)
[英]What happens if I use update-alternatives to manage python versions instead of virtualenv or pyenv?
[英]What shebang to use for Python scripts run under a pyenv virtualenv
當 Python 腳本應該從pyenv
virtualenv
運行時,該文件的正確shebang是什么?
作為示例測試用例,我的系統 (OS X) 上的默認 Python 沒有安裝pandas
。 pyenv virtualenv venv_name
可以。 我嘗試從 virtualenv 獲取 Python 可執行文件的路徑。
pyenv activate venv_name
which python
Output:
/Users/username/.pyenv/shims/python
所以我做了我的例子script.py
:
#!/Users/username/.pyenv/shims/python
import pandas as pd
print 'success'
但是當我嘗試運行腳本時(從“venv_name”中),我得到了一個錯誤:
./script.py
Output:
./script.py: line 2: import: command not found
./script.py: line 3: print: command not found
雖然直接在命令行上運行該路徑(從“venv_name”中)工作正常:
/Users/username/.pyenv/shims/python script.py
Output:
success
和:
python script.py # Also works
Output:
success
什么是合適的 shebang? 理想情況下,我想要一些通用的東西,以便它指向 Python,無論我當前的 venv 是什么。
我真的不知道為什么用全路徑調用解釋器對您不起作用,我一直都在使用它,但是如果您想使用環境中的python解釋器,應該這樣做:
#!/usr/bin/env python
這樣,您就可以在環境中搜索要使用的python解釋器。
如果您需要使用更多的shell,則可以輸入#!
在shebang行中,您可以使用簡單的shell腳本啟動文件,該腳本會在同一文件上啟動Python。
#!/bin/bash
"exec" "pyenv" "exec" "python" "$0" "$@"
# the rest of your Python script can be written below
由於使用了引號,Python不會執行第一行,而是將字符串串聯在一起作為模塊docstring……這實際上忽略了它。
你可以在這里看到更多。
如您所料,無論控制腳本的環境如何,您都應該能夠使用shebang中虛擬環境python的完整路徑來選擇/控制腳本運行的環境。
在對您的問題VPfB的評論中,您發現/Users/username/.pyenv/shims/python
是一個exec $pyenv_python
的shell腳本。 您應該能夠echo $pyenv_python
以確定真正的python並將其用作您的shebang。
另請參閱: https : //unix.stackexchange.com/questions/209646/how-to-activate-virtualenv-when-a-python-script-starts
嘗試pyenv virtualenvs
查找虛擬環境目錄的列表。
然后,您可能會發現使用shebang這樣的東西:
#!/Users/username/.pyenv/python/versions/venv_name/bin/python
import pandas as pd
print 'success'
...將使腳本能夠在其他(虛擬或非虛擬)環境中使用選定的虛擬環境工作:
(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
$
訣竅是,如果您專門調出虛擬環境的python二進制文件,則python會在該二進制文件的路徑位置查找支持文件,並最終使用周圍的虛擬環境。 (請參閱每篇virtualenv的工作原理? )
也許您需要檢查文件權限:
sudo chmod +x script.py
它並沒有完全回答Q,但是我認為這是通過言辭提出的建議,這是做您想要的事情的一種更好的方法。 我已經詳細說明了一些內容,並對其進行了更多解釋,以及如何動態選擇要使用的python:
#!/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 "$0" "$@"
elif [ -x $ALTERNATIVE_PYTHON ]; then
echo Using alternative python $ALTERNATIVE_PYTHON
exec $ALTERNATIVE_PYTHON "$0" "$@"
else
echo Using fallback python $FALLBACK_PYTHON
exec python3 "$0" "$@"
fi
exit 127
'''
__doc__ = """What this file does"""
print(__doc__)
import platform
print(platform.python_version())
要擴展到這個答案,在 99% 的情況下,如果您的環境中有 python,您可以使用:
#!/usr/bin/env python
但是,對於遵循相同語法的linux
上的自定義venv
對我不起作用,因為venv
創建了一個到 python 解釋器的鏈接, venv
是從它創建的,所以我必須執行以下操作:
#!/path/to/the/venv/bin/python
但是本質上,您可以在終端上調用 python 是您將在#!
.
如果你只想要一個簡單選擇 pyenv virtualenv 的腳本,你可以使用一個 Bash 腳本和你的源代碼作為heredoc ,如下所示:
#!/bin/bash
PYENV_VERSION=<your_pyenv_virtualenv_name> python - $@ <<EOF
import sys
print(sys.argv)
exit
EOF
我做了一些額外的測試。 以下也適用:
#!/usr/bin/env -S PYENV_VERSION=<virtual_env_name> python
/usr/bin/env python
將不起作用,因為它不知道虛擬環境。
假設您的main.py
位於./venv
目錄旁邊,您需要使用 venv 目錄中的venv
。 或者換句話說,使用這個 shebang:
#!venv/bin/python
現在你可以這樣做:
./main.py
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.