Как может работать функция оболочки, если она работает в 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