簡體   English   中英

在 pyenv virtualenv 下運行的 Python 腳本使用什么 shebang

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM