Как может работать функция оболочки, если она работает в virtualenv?

Как должна функция bash проверить, запущена ли она внутри виртуального виртуального Python?

Два подхода, которые приходят на ум, следующие:

[[ "$(type -t deactivate)" != function ]]; INVENV=$?

или

[[ "x$(which python)" != "x$VIRTUAL_ENV/bin/python" ]]; INVENV=$?

(Примечание: для $INVENV требуется <1 > , если мы находимся внутри virtualenv, а 0 - это то, что заставляет предыдущие тесты выше.)

Есть ли что-то менее взломанное?

Ответы

Ответ 1

Собственно, я просто нашел аналогичный вопрос, из которого можно легко получить ответ на этот вопрос:

Python: Определите, работает ли внутри virtualenv

Например, оболочка script может использовать что-то вроде

python -c 'import sys; print (sys.real_prefix)' 2>/dev/null && INVENV=1 || INVENV=0

(Спасибо Кристиану Лонгу за то, что он показал, как это решение работает с Python 3).

EDIT: здесь более прямое (следовательно, более четкое и чистое) решение (взятие ответа от комментария JuanPablo):

INVENV=$(python -c 'import sys; print ("1" if hasattr(sys, "real_prefix") else "0")')

Ответ 2

if [[ "$VIRTUAL_ENV" != "" ]]
then
  INVENV=1
else
  INVENV=0
fi
// or shorter if you like:
[[ "$VIRTUAL_ENV" == "" ]]; INVENV=$?

EDIT: поскольку @ThiefMaster упоминает в комментариях в определенных условиях (например, при запуске новой оболочки - возможно, в tmux или screen - из активного виртуального пользователя) это проверка может завершиться неудачей (однако запуск новых оболочек из virtualenv также может вызвать другие проблемы, я бы не рекомендовал его).

Ответ 3

Если вы используете virtualenvwrappers, есть сценарии pre/post, которые запускаются, которые могут установить для вас INVENV.

Или что я делаю, поместите следующее в свой .bashrc и создайте файл с именем .venv в вашем рабочем каталоге (для django), чтобы виртуальный env автоматически загружался, когда вы cd в каталог

export PREVPWD=`pwd`
export PREVENV_PATH=

handle_virtualenv(){
    if [ "$PWD" != "$PREVPWD" ]; then
        PREVPWD="$PWD";
        if [ -n "$PREVENV_PATH" ]; then
            if [ "`echo "$PWD" | grep -c $PREVENV_PATH`" = "0"  ]; then
                deactivate
                unalias python 2> /dev/null
                PREVENV_PATH=
            fi
        fi

        # activate virtualenv dynamically
        if [ -e "$PWD/.venv" ] && [ "$PWD" != "$PREVENV_PATH" ]; then
            PREVENV_PATH="$PWD"
            workon `basename $PWD`
            if [ -e "manage.py" ]; then
                alias python='python manage.py shell_plus'
            fi
        fi
    fi
}

export PROMPT_COMMAND=handle_virtualenv