Подтвердить что ты не робот

То, что shebang использовать для скриптов python, выполняется под pyenv virtualenv

Когда предполагается, что python script запускается из pyenv virtualenv, что является правильным shebang для файла?

В качестве примера тестового примера, в python по умолчанию для моей системы (OSX) не установлен pandas. Pyenv virtualenv venv_name делает. Я попытался получить путь к исполняемому файлу python из virtualenv.

$ pyenv activate venv_name
(venv_name)$ which python
/Users/username/.pyenv/shims/python


Поэтому я сделал свой пример script.py:

#!/Users/username/.pyenv/shims/python
import pandas as pd
print 'success'


Но когда я попытался запустить script, я получил сообщение об ошибке:

(venv_name) $ ./script.py
./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
success

(venv_name) $ python script.py # also works
success

Что для этого нужно? В идеале, я хочу что-то общее, чтобы оно указывало на питон любого моего текущего venv.

4b9b3361

Ответ 1

Я действительно не знаю, почему вызов интерпретатора с полным путем не сработает для вас, я использую его все время, но если вы хотите использовать интерпретатор python, который находится в вашей среде, вы должны сделать:

#!/usr/bin/env python

Таким образом вы выполняете поиск в среде, в которой используется интерпретатор python.

Ответ 2

Если вам нужно использовать больше оболочки, чем вы можете поместить в строку #! shebang, вы можете запустить файл с помощью простой оболочки script, которая запускает Python в том же файле.

#!/bin/bash
"exec" "pyenv" "exec" "python" "$0" "[email protected]"
# the rest of your Python script can be written below

Из-за цитирования Python не выполняет первую строку и вместо этого объединяет строки для модуля docstring... который фактически игнорирует его.

Здесь вы можете увидеть .

Ответ 3

Как вы и ожидали, вы должны иметь возможность использовать полный путь к виртуальной среде python в shebang для выбора/управления средой, в которой работает script, независимо от среды управления script.

В комментариях к вашему вопросу VPfB вы обнаружите, что /Users/username/.pyenv/shims/python представляет собой оболочку script, которая выполняет exec $pyenv_python. Вы должны иметь возможность echo $pyenv_python определить реальный питон и использовать его в качестве своего сибанга.

Смотрите также: 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'

... позволит script работать с использованием выбранной виртуальной среды в других (виртуальных или нет) средах:

(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 просматривает это место двоичного пути для поддерживающих файлов и заканчивает работу с использованием окружающей виртуальной среды. (См. Per Как работает virtualenv?)

Ответ 4

может быть, вам нужно проверить права доступа к файлу:

sudo chmod +x script.py

Ответ 5

Это не совсем ответ на вопрос, но это предложение от ephiement, я думаю, гораздо лучший способ сделать то, что вы хотите. Я немного развил и добавил еще несколько объяснений о том, как это работает и как вы можете динамически выбирать питон для использования:

#!/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" "[email protected]"
elif [ -x $ALTERNATIVE_PYTHON ]; then
    echo Using alternative python $ALTERNATIVE_PYTHON
    exec $ALTERNATIVE_PYTHON "$0" "[email protected]"
else
    echo Using fallback python $FALLBACK_PYTHON
    exec python3 "$0" "[email protected]"
fi
exit 127
'''

__doc__ = """What this file does"""
print(__doc__)
import platform
print(platform.python_version())