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

Как запустить virtualenv активировать в Bash script

Как вы создаете Bash script, чтобы активировать виртуальный файл Python?

У меня есть структура каталогов, вроде:

.env
    bin
        activate
        ...other virtualenv files...
src
    shell.sh
    ...my code...

Я могу активировать свой virtualenv:

[email protected]:src$ . ../.env/bin/activate
(.env)[email protected]:src$

Однако делать то же самое с Bash script ничего не делает:

[email protected]:src$ cat shell.sh
#!/bin/bash
. ../.env/bin/activate
[email protected]:src$ ./shell.sh
[email protected]:src$ 

Что я делаю неправильно?

4b9b3361

Ответ 1

Когда вы используете источник, вы загружаете активацию script в свою активную оболочку.

Когда вы делаете это в script, вы загружаете его в ту оболочку, которая завершается, когда ваш script заканчивается, и вы вернетесь в свою оригинальную неактивированную оболочку.

Ваш лучший вариант - сделать это в функции

activate () {
  . ../.env/bin/activate
}

или псевдоним

alias activate=". ../.env/bin/activate"

Надеюсь, что это поможет.

Ответ 2

Вы можете вызвать bash script с помощью источника.

Вот пример:

#!/bin/bash
# Let call this script venv.sh
source "<absolute_path_recommended_here>/.env/bin/activate"

На вашей оболочке просто назовите ее так:

> source venv.sh

Или как @outmind предложил: (Обратите внимание, что это не работает с zsh)

> . venv.sh

Там вы увидите индикацию оболочки в своем приглашении.

Ответ 3

Хотя он не добавляет префикс "(.env)" в приглашение оболочки, я обнаружил, что этот script работает так, как ожидалось.

#!/bin/bash
script_dir=`dirname $0`
cd $script_dir
/bin/bash -c ". ../.env/bin/activate; exec /bin/bash -i"

например.

[email protected]:~/src$ which pip
/usr/local/bin/pip
[email protected]:~/src$ which python
/usr/bin/python
[email protected]:~/src$ ./shell
[email protected]:~/src$ which pip
~/.env/bin/pip
[email protected]:~/src$ which python
~/.env/bin/python
[email protected]:~/src$ exit
exit

Ответ 4

Sourcing запускает команды оболочки в вашей текущей оболочке. Когда вы находитесь внутри script, как вы делаете это выше, вы воздействуете на среду для этого script, но когда script завершается, изменения среды отменены, так как они фактически вышли из сферы действия.

Если вы намерены запускать команды оболочки в virtualenv, вы можете сделать это в своем script после поиска активировать script. Если вы намерены взаимодействовать с оболочкой внутри virtualenv, вы можете создать под-оболочку внутри вашего script, которая наследует среду.

Ответ 5

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

#!/bin/bash

commandA --args

# Run commandB in a subshell and collect its output in $VAR
VAR=$(
    PATH=$PATH:/opt/bin
    . /path/to/activate > /dev/null
    commandB  # tool from /opt/bin that requires virtualenv
)

# Use the output of the commandB later
commandC "${VAR}"

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

  • commandA или commandB существуют в /opt/bin
  • эти команды терпят неудачу под virtualenv
  • вам нужно множество различных virtualenvs

Ответ 6

Что происходит с поиском bash script для?

  • Если вы намереваетесь переключаться между несколькими виртуальными окнами или быстро вводить один virtualenv, попробуйте ли вы virtualenvwrapper? Он предоставляет множество utils, таких как workon venv, mkvirtualenv venv и т.д.

  • Если вы просто запустите python script в определенном virtualenv, используйте /path/to/venv/bin/python script.py для его запуска.

Ответ 7

Вот сценарий, который я часто использую

#!/bin/bash -x
PWD='pwd'
/usr/local/bin/virtualenv --python=python3 venv
echo $PWD
activate () {
    . $PWD/venv/bin/activate
}

activate

Ответ 8

Вы должны использовать несколько команд в одной строке. например:

os.system(". Projects/virenv/bin/activate && python Projects/virenv/django-project/manage.py runserver")

Когда вы активируете свою виртуальную среду в одной строке, я думаю, что она забывает о других командных строках, и вы можете предотвратить это, используя несколько команд в одной строке. У меня это сработало :)