web-dev-qa-db-fra.com

Comment source virtualenv activer dans un script Bash

Comment créez-vous un script Bash pour activer une virtualenv Python?

J'ai une structure de répertoire comme:

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

Je peux activer mon virtualenv par:

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

Cependant, faire la même chose à partir d'un script Bash ne fait rien:

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

Qu'est-ce que je fais mal?

65
Cerin

Lorsque vous sourcez, vous chargez le script d'activation dans votre shell actif.

Lorsque vous le faites dans un script, vous le chargez dans ce shell qui se termine lorsque votre script se termine et que vous revenez à votre shell non activé d'origine.

Votre meilleure option serait de le faire dans une fonction

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

ou un alias

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

J'espère que cela t'aides.

49
richo

Vous devriez appeler le script bash en utilisant source.

Voici un exemple:

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

Sur votre Shell, appelez ça comme ça:

> source venv.sh

Ou comme suggéré par @outmind: (Notez que cela ne fonctionne pas avec zsh)

> . venv.sh

Voilà, l’indication Shell sera placée sur votre invite.

39
Flavio Garcia

Bien qu'il n'ajoute pas le préfixe "(.env)" à l'invite du shell, j'ai découvert que ce script fonctionnait comme prévu.

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

par exemple.

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
13
Cerin

Sourcing exécute des commandes Shell dans votre Shell actuel. Lorsque vous sourcez à l'intérieur d'un script comme vous le faites ci-dessus, vous affectez l'environnement pour ce script, mais lorsque le script se ferme, les modifications de l'environnement sont annulées car elles sont réellement hors de portée.

Si votre intention est d'exécuter des commandes Shell dans virtualenv, vous pouvez le faire dans votre script après avoir recherché le script d'activation. Si votre intention est d'interagir avec un shell dans virtualenv, vous pouvez créer un sous-shell dans votre script qui hériterait de l'environnement.

8
zigg

Voici le script que j'utilise souvent

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

activate
0
Sand1512

Vous pouvez également faire cela en utilisant un sous-shell pour mieux contenir votre utilisation - voici un exemple pratique:

#!/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}"

Ce style est particulièrement utile lorsque

  • commandA ou commandB existe dans /opt/bin
  • ces commandes échouent sous virtualenv
  • vous avez besoin d'une variété de virtualenv différents
0
ti7

A quoi sert de rechercher le script bash?

  1. Si vous avez l'intention de basculer entre plusieurs virtualenv ou d'entrer rapidement un virtualenv, avez-vous essayé virtualenvwrapper? Il fournit de nombreux utilitaires tels que workon venv, mkvirtualenv venv et ainsi de suite.

  2. Si vous venez d'exécuter un script python dans certains virtualenv, utilisez /path/to/venv/bin/python script.py pour l'exécuter.

0
iMom0

Vous devez utiliser plusieurs commandes sur une ligne. par exemple:

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

lorsque vous activez votre environnement virtuel sur une seule ligne, je pense qu’il oublie d’autres lignes de commande et vous pouvez éviter cela en utilisant plusieurs commandes sur une seule ligne. Cela a fonctionné pour moi :)

0