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?
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.
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.
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
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.
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
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
A quoi sert de rechercher le script bash?
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.
Si vous venez d'exécuter un script python dans certains virtualenv, utilisez /path/to/venv/bin/python script.py
pour l'exécuter.
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 :)