Як джерело virtualenv активувати в сценарії Bash


98

Як створити сценарій Bash для активації Python virtualenv?

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

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

Я можу активувати свій virtualenv за допомогою:

user@localhost:src$ . ../.env/bin/activate
(.env)user@localhost:src$

Однак те ж саме із сценарієм Bash нічого не робить:

user@localhost:src$ cat shell.sh
#!/bin/bash
. ../.env/bin/activate
user@localhost:src$ ./shell.sh
user@localhost:src$ 

Що я роблю не так?


6
Коли ви запускаєте сценарій оболонки, ви фактично створюєте нову оболонку. Сенс використання sourceполягає в тому, щоб змінити щось у поточній оболонці. Ви можете використовувати python virtualenv, використовуючи повний шлях ./env/bin/python.
Пабло Наварро,

@NgureNyaga, Ні, це питання не таке, як у мене. Вони запитують, як взяти джерело з довільного місця. Я вже знаю, як це зробити. Я запитую, як шукати джерело в спеціальному скрипті bash та підтримувати його.
Cerin

Відповіді:


79

Під час джерела ви завантажуєте сценарій активації у свою активну оболонку.

Коли ви робите це в сценарії, ви завантажуєте його в ту оболонку, яка завершується, коли ваш сценарій закінчується, і ви повертаєтесь до своєї початкової, неактивованої оболонки.

Найкращим варіантом було б зробити це у функції

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

або псевдонім

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

Сподіваюся, це допомагає.


для Windows c: \ tutorial>. \ env \ Scripts \ activate
max4ever

6
Я абсолютно не підозрював, що саме це відбувалося, коли я роблю джерело. Це значно змінило мої скрипти Bash на краще. Дякую!
Роберт Таунлі,

1
Ваша ідея з псевдонімом також добре спрацювала для мене. Тільки примітка: мені довелося помістити його (псевдонім abcdef = "source ... / bin / activate") у свій скрипт .zshrc (або .bashrc для користувачів bash), щоб він працював.
shahins

Це гарне рішення, якщо у вас є virtualenvs, що використовують ім’я папки за замовчуванням. Раніше у мене було більше одного репозиторію в папці, роблячи безлад на virtualenvs. Зараз я перейшов до цього типового режиму.
3manuek

3
Я зовсім новачок у bash тощо. Чи можете ви розгорнути цей приклад, щоб він показував повний сценарій?
AljoSt

57

Вам слід викликати скрипт bash за допомогою джерела.

Ось приклад:

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

На вашій оболонці просто назвіть це так:

> source venv.sh

Або як запропонував @outmind: (Зверніть увагу, що це не працює з zsh)

> . venv.sh

Ось, індикація оболонки буде розміщена у вашому запиті.


2
або навіть просто ". venv.sh"
вийшов

що б я не намагався, це source "/home/surest/Desktop/testservers/TEST_VENV/venv3/bin/activate"видає:/home/surest/Desktop/testservers/TEST_VENV/py3.sh: 10: /home/surest/Desktop/testservers/TEST_VENV/py3.sh: source: not found

Я також нічого не отримую, коли набираю текст під командою which sourceоболонки, але source venv3/bin/activateроблю те, що я очікував, і відкриваю venv. ...

Чому це працює, але source ./env/bin/activate(з тим самим #!/bin/bashпрефіксом) ні? Яка різниця між використанням лапок і ні?
чорне місце

У мене немає проблем із використанням джерела всередині сценарію без лапок. Я бачу проблему з source ./env/bin/activateтим, що це відносно шляху, яким ви біжите? Якщо ви зміните каталог всередині сценарію, то ви можете стати відносним.
Флавіо Гарсія,

13

Хоча він не додає префікс "(.env)" до підказки оболонки, я виявив, що цей сценарій працює належним чином.

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

напр

user@localhost:~/src$ which pip
/usr/local/bin/pip
user@localhost:~/src$ which python
/usr/bin/python
user@localhost:~/src$ ./shell
user@localhost:~/src$ which pip
~/.env/bin/pip
user@localhost:~/src$ which python
~/.env/bin/python
user@localhost:~/src$ exit
exit

5
технічно ви створюєте під оболонку. Це не обов’язково проблема, але ви повинні прописати це для ОП.
Річо

Це спрацювало, але раніше мені довелося дати дозвіл на мій файл "активувати".
Адріан Лопес,

1
Це працює в 2019 році! На macos мені просто довелося змінити /bin/bashна/usr/bin/env bash
valem

Працює в Ubuntu 18.04 AWS EC2 у 2020 році. Цікаво, як мене деактивувати, використовуючи ту саму логіку?
CSF Junior

Ви deactivateз допоміжної оболонки за допомогою exitабо Ctrl + d
Alexx Roche

10

Джерело запускає команди оболонки у вашій поточній оболонці. Коли ви виконуєте джерело всередині сценарію, як це робиться вище, ви впливаєте на середовище для цього сценарію, але коли сценарій виходить, зміни середовища скасовуються, оскільки вони фактично вийшли за рамки.

Якщо ви маєте намір запустити команди оболонки у virtualenv, ви можете зробити це у своєму сценарії після пошуку сценарію активації. Якщо ви маєте намір взаємодіяти з оболонкою всередині virtualenv, тоді ви можете створити допоміжну оболонку всередині вашого сценарію, яка успадкує оточення.


2

Ось сценарій, який я часто використовую. Запустіть як$ source script_name

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

activate

1

Для чого потрібен пошук скрипта bash?

  1. Якщо ви маєте намір переключатися між кількома віртуальними програмами або швидко вводити один віртуальний файл, чи пробували ви virtualenvwrapper? Це дає багато утилітами , як workon venv, mkvirtualenv venvі так далі.

  2. Якщо ви просто запускаєте скрипт python у певному virtualenv, використовуйте /path/to/venv/bin/python script.pyдля його запуску.


Власне, я хотів би зателефонувати workon ...із скрипта bash. (Тому що я хочу виконувати подальші матеріали щоразу після кожного запуску.) Однак я не можу знайти спосіб змусити це працювати.
Даніель Б.

1

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

#!/bin/bash

commandA --args

# Run commandB in a subshell and collect its output in $VAR
# NOTE
#  - PATH is only modified as an example
#  - output beyond a single value may not be captured without quoting
#  - it is important to discard (or separate) virtualenv activation stdout
#    if the stdout of commandB is to be captured
#
VAR=$(
    PATH="/opt/bin/foo:$PATH"
    . /path/to/activate > /dev/null  # activate virtualenv
    commandB  # tool from /opt/bin/ which requires virtualenv
)

# Use the output from commandB later
commandC "$VAR"

Цей стиль особливо корисний, коли

  • інша версія commandAабо commandCіснує під/opt/bin
  • commandBіснує в системі PATHабо є дуже поширеним
  • ці команди виходять з ладу під virtualenv
  • потрібно безліч різних віртуальних засобів

Не забудьте подвоїти лапки, інакше у $(...)вас будуть відсутні пробіли та вкладки, що містяться у вихідних даних.
Ерік

"${VAR}"строго еквівалентно, "$VAR"вам не потрібні фігурні дужки навколо змінних оболонки, оскільки подвійні лапки насправді потужніші. Виняток при використанні модифікаторів , таких як, наприклад"${VAR:-default_value}"
Ерік

PATH=$PATH:/opt/binпотребує правильного цитування для обробки шляхів із пробілами та вкладками.
Ерік

@Eric Дякую, хоча ти можеш використовувати editкнопку під повідомленнями, щоб запропонувати зміни до них! Далі, нехай буде відомо, що, хоча це часто є вимогою та важливою для безпеки, кожен, хто свідомо додає IFSсимволи, PATHє терористом.
ti7

0

Вам слід використовувати кілька команд в одному рядку. наприклад:

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

коли ви активуєте своє віртуальне середовище в одному рядку, я думаю, воно забуває про інші командні рядки, і ви можете запобігти цьому, використовуючи кілька команд в одному рядку. У мене це вийшло :)


0

Коли я вивчав venv, я створив сценарій, який нагадував мені, як його активувати.

#!/bin/sh
# init_venv.sh
if [ -d "./bin" ];then
  echo "[info] Ctrl+d to deactivate"
  bash -c ". bin/activate; exec /usr/bin/env bash --rcfile <(echo 'PS1=\"(venv)\${PS1}\"') -i"
fi

Це має ту перевагу, що змінює підказку.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.