2015-04-09 2 views
6

Я новичок в сценариях оболочки, но я хочу создать скрипт bash для активации/деактивации виртуальной среды с помощью virtualenv. Затем я хочу использовать этот скрипт, как сервис в Ubuntu, копируя его внутри папки /etc/init.d.как деактивировать virtualenv из сценария bash

В моем сценарии, у меня есть переменная, как это: VENV=/opt/odoo/odoo_server/venv_oddo/bin

Эта переменная представляет путь бен в моей виртуальной среде.

Внутри сценария, я могу активировать виртуальное с этим состоянием происходит утверждение: . ${VENV}/activate

Это возможно потому, что активировать файл в каталоге бен в виртуальной среде.

Но я не знаю утверждения, которое будет использоваться в моем скрипте для деактивации моей виртуальной среды. Я не могу это сделать: . ${VENV}/deactivate

Проблема в том, что файл не деактивирован, но деактивирована функция внутри файла bin/activate в виртуальной среде.

+1

Если ваш скрипт работает в подпроцессе, виртуальный сервер перестанет существовать, когда скрипт существует. Явное указание 'deactivate' перед выходом не является ни необходимым, ни полезным. – tripleee

ответ

2

Это будет трудно сделать услугу, как, что полезно ,

. ${VENV}/activate # note the dot 

или

source ${VENV}/activate 

будет source в activate сценарий, т.е. запустить его содержимого , как если бы они были частью оболочки или сценария, где источником их. virtualenvironmentactivateis designed for this usage. В отличие от этого, только выполнение сценария обычно с

${VENV}/activate # note: NO dot and NO 'source' command 

будет работать его содержание в субоболочке и не будет иметь никакого полезного эффекта.

Однако ваш скрипт обслуживания уже будет запущен в своей подоконной. Поэтому, за исключением любых команд python, которые вы запускаете как часть процесса запуска службы, это не будет иметь никакого эффекта.

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

+0

Благодарим вас за ответ, но я не понимаю, когда вы сказали: _Просто выполнение сценария обычно (так, что его содержимое будет работать в подоболочке) не будет иметь никакого полезного эффекта ._ – edkalel

+0

Я отредактировал свой ответ , @edkalel, теперь его легче понять? Ключевым моментом является то, что 'activate' влияет только на shell/script, где он получен, а не на всю систему. –

+0

Благодарим вас за разъяснения. Я думаю, что я это уже понял. Затем, если я использую 'activate' внутри моего bash-скрипта (с. Или source), виртуальная среда будет активирована только внутри скрипта, а не снаружи в оболочке. – edkalel

3

Всего deactivate. Он будет работать как в скрипте, так и в командной строке, если вы используете bash.

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

. $VENV/bin/activate 
/path/to/my/script.py --parameters 

это, как правило, предпочтительнее делать

$VENV/bin/python /path/to/my/script --parameters 

Поверь мне, это сэкономит вам время отладки)

+1

Благодарим вас за ответ, но если я использую 'deactivate' внутри скрипта bash, то при его выполнении я получаю следующее сообщение в оболочке:' deactivate: command not found' – edkalel

+1

Вы не можете использовать 'deactivate' в оболочке скрипт без предварительного поиска скрипта, который определяет эту функцию. См. Мой отдельный ответ на этот вопрос. –

0

copy deactivate code in $ {VENV}/активировать.

вставить ~/.bashrc

deactivate() { 
    # reset old environment variables 
    if [ -n "$_OLD_VIRTUAL_PATH" ] ; then 
     PATH="$_OLD_VIRTUAL_PATH" 
     export PATH 
     unset _OLD_VIRTUAL_PATH 
    fi 
    if [ -n "$_OLD_VIRTUAL_PYTHONHOME" ] ; then 
     PYTHONHOME="$_OLD_VIRTUAL_PYTHONHOME" 
     export PYTHONHOME 
     unset _OLD_VIRTUAL_PYTHONHOME 
    fi 

    # This should detect bash and zsh, which have a hash command that must 
    # be called to get it to forget past commands. Without forgetting 
    # past commands the $PATH changes we made may not be respected 
    if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then 
     hash -r 
    fi 

    if [ -n "$_OLD_VIRTUAL_PS1" ] ; then 
     PS1="$_OLD_VIRTUAL_PS1" 
     export PS1 
     unset _OLD_VIRTUAL_PS1 
    fi 

    unset VIRTUAL_ENV 
    if [ ! "$1" = "nondestructive" ] ; then 
     # Self destruct! 
     unset -f deactivate 
    fi 
} 

команды запуска.

$ $VENV/activate 
$ deactivate 

Я выборочно использовал без проблем python 2.7 и python 3.5 таким образом.

Я хочу знать причину отрицательной оценки.

+0

Я думаю, что минусы связаны с тем, что (1) это решение не чистое, и (2) оно прямо не решает указанную проблему. Обычно .bashrc используется только для интерактивной оболочки, в то время как вопрос касается сценариев bash. Но я не вижу действительно чистого решения. – MarSoft

+0

UPD: он не работает, потому что _OLD_VIRTUAL_PATH является локальной переменной и не экспортируется ... Увы. Нет хорошего решения. Никакого решения. – MarSoft

1

deactivate «команда», предоставляемая virtualenvwrapper, на самом деле является функцией оболочки, аналогичной для workon. Если у вас есть виртуальный env active, вы можете перечислить имена этих функций с помощью typeset -F.

Чтобы использовать их в скрипте, их необходимо определить там, потому что функции оболочки не распространяются на дочерние оболочки.

Чтобы определить эти функции, подключит virtualenvwrapper.sh сценария в сценарии оболочки, где вы собираетесь вызывать эти функции, например:

source $(which virtualenvwrapper.sh) 

Это позволяет вызывать эти функции в сценарии оболочки, как вы могли бы сделать в оболочка:

deactivate 

Update: что я описал работу для других функций, предусмотренных virtualenvwrapper (например workon). Я неправильно предположил, что это будет работать и для деактивации, но это более сложный случай, потому что это функция, которая будет определена только в оболочке, где был запущен workon или activate.

+0

Это не будет работать для простых 'virtualenv' или' python3 -m venv'. – MarSoft

+0

Возможно, придется использовать метод брасизи (хотя мне это не нравится). На самом деле я думаю, что обычно достаточно просто восстановить $ PATH. – MarSoft