So aktivieren Sie virtualenv in einem Bash-Skript

96

Wie erstellt man ein Bash-Skript, um eine Python-Virtualenv zu aktivieren?

Ich habe eine Verzeichnisstruktur wie:

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

Ich kann meine virtuelle Umgebung aktivieren durch:

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

Dasselbe mit einem Bash-Skript zu tun, bewirkt jedoch nichts:

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

Was mache ich falsch?

Cerin
quelle
6
Wenn Sie ein Shell-Skript ausführen, erstellen Sie tatsächlich eine neue Shell. Der Sinn der Verwendung sourcebesteht darin, etwas in der aktuellen Shell zu ändern. Sie können die Python des virtualenv über den vollständigen Pfad verwenden ./env/bin/python.
Pablo Navarro
@NgureNyaga, Nein, diese Frage ist nicht die gleiche wie meine. Sie fragen, wie sie von einem beliebigen Ort aus beziehen sollen. Ich weiß schon, wie das geht. Ich frage, wie man innerhalb eines benutzerdefinierten Bash-Skripts eine Quelle erstellt und die Quelle verwaltet.
Cerin

Antworten:

76

Wenn Sie eine Quelle erstellen, laden Sie das Aktivierungsskript in Ihre aktive Shell.

Wenn Sie dies in einem Skript tun, laden Sie es in die Shell, die beendet wird, wenn Ihr Skript beendet ist und Sie zu Ihrer ursprünglichen, nicht aktivierten Shell zurückkehren.

Ihre beste Option wäre, dies in einer Funktion zu tun

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

oder ein Alias

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

Hoffe das hilft.

Richo
quelle
für Windows C: \ Tutorial>. \ env \ Scripts \ aktivieren
max4ever
5
Ich hatte absolut keine Ahnung, was passiert ist, als ich die Quelle erstellt habe. Dies hat mein Bash-Scripting erheblich zum Besseren verändert. Danke dir!
Robert Townley
1
Ihre Alias-Idee hat auch bei mir gut funktioniert. Nur eine Anmerkung: Ich musste es (alias abcdef = "source ... / bin / enabled") in mein .zshrc-Skript (oder .bashrc für die Bash-Benutzer) einfügen, damit es funktioniert.
Shahins
Dies ist eine gute Lösung, wenn Ihre virtuellen Umgebungen den Standardordnernamen verwenden. Früher hatte ich mehr als ein Repo im Ordner, was die virtuellen Umgebungen durcheinander brachte. Ich habe jetzt zu dieser Standardeinstellung gewechselt.
3manuek
3
Ich bin ziemlich neu in Bash usw. Können Sie dieses Beispiel so erweitern, dass es das vollständige Skript zeigt?
AljoSt
54

Sie sollten das Bash-Skript mit source aufrufen.

Hier ist ein Beispiel:

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

Nennen Sie es auf Ihrer Shell einfach so:

> source venv.sh

Oder wie von @outmind vorgeschlagen: (Beachten Sie, dass dies mit zsh nicht funktioniert.)

> . venv.sh

Los geht's, die Shell-Anzeige wird auf Ihrer Eingabeaufforderung platziert.

Flavio Garcia
quelle
2
oder auch nur ". venv.sh"
outmind
egal was ich versuche, dies source "/home/surest/Desktop/testservers/TEST_VENV/venv3/bin/activate"erzeugt:/home/surest/Desktop/testservers/TEST_VENV/py3.sh: 10: /home/surest/Desktop/testservers/TEST_VENV/py3.sh: source: not found
Ich bekomme auch nichts, wenn ich which sourcean einer Shell-Eingabeaufforderung source venv3/bin/activatetippe , aber das tue, was ich erwarte und das Venv öffne. ...
Warum funktioniert das, aber source ./env/bin/activate(mit demselben #!/bin/bashPräfix) nicht? Was ist der Unterschied zwischen der Verwendung von Anführungszeichen und nicht?
Blacksite
Ich habe kein Problem damit, die Quelle im Skript ohne Anführungszeichen zu verwenden. Ich sehe ein Problem mit, source ./env/bin/activateweil dies relativ zu dem Pfad ist, den Sie laufen, oder? Wenn Sie das Verzeichnis innerhalb des Skripts ändern, können Sie relativ werden.
Flavio Garcia
13

Obwohl das Präfix "(.env)" nicht zur Shell-Eingabeaufforderung hinzugefügt wird, hat dieses Skript wie erwartet funktioniert.

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

z.B

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
Cerin
quelle
5
Technisch gesehen erzeugen Sie eine Unterschale. Es ist nicht unbedingt ein Problem, aber Sie sollten das für das OP formulieren.
Richo
Es hat funktioniert, aber ich musste vorher meine "Aktivierungs" -Datei genehmigen.
Adrian Lopez
1
Das funktioniert 2019! Auf macos Ich musste nur die ändern /bin/bashzu/usr/bin/env bash
valem
Funktioniert in Ubuntu 18.04 AWS EC2 im Jahr 2020. Ich frage mich, wie ich mit derselben Logik deaktivieren kann.
CSF Junior
Sie deactivateaus der Subshell mit exitoder Strg + d
Alexx Roche
10

Beim Sourcing werden Shell-Befehle in Ihrer aktuellen Shell ausgeführt. Wenn Sie innerhalb eines Skripts wie oben beschrieben eine Quelle erstellen, wirkt sich dies auf die Umgebung dieses Skripts aus. Wenn das Skript jedoch beendet wird, werden die Umgebungsänderungen rückgängig gemacht, da sie praktisch außerhalb des Gültigkeitsbereichs liegen.

Wenn Sie Shell-Befehle in der virtuellen Umgebung ausführen möchten, können Sie dies in Ihrem Skript tun, nachdem Sie das Aktivierungsskript bezogen haben. Wenn Sie mit einer Shell innerhalb der virtuellen Umgebung interagieren möchten, können Sie eine Sub-Shell in Ihrem Skript erzeugen, die die Umgebung erben würde.

Zickzack
quelle
2

Hier ist das Skript, das ich oft benutze. Führen Sie es als$ source script_name

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

activate
Sand1512
quelle
1

Wofür dient die Beschaffung des Bash-Skripts?

  1. Wenn Sie beabsichtigen, zwischen mehreren virtuellen Umgebungen zu wechseln oder schnell eine virtuelle Umgebung einzugeben, haben Sie es versucht virtualenvwrapper? Es bietet eine Menge utils wie workon venv, mkvirtualenv venvund so weiter.

  2. Wenn Sie nur ein Python-Skript in einer bestimmten virtuellen Umgebung ausführen, verwenden Sie es /path/to/venv/bin/python script.py, um es auszuführen.

iMom0
quelle
Eigentlich möchte ich workon ...von einem Bash-Skript aus aufrufen . (Weil ich jedes Mal beim Start weitere Dinge ausführen möchte.) Ich kann jedoch keinen Weg finden, es zum Laufen zu bringen.
Daniel B.
1

Sie können dies auch mit einer Unterschale tun, um Ihre Verwendung besser einzudämmen - hier ein praktisches Beispiel:

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

Dieser Stil ist besonders hilfreich, wenn

  • eine andere Version von commandAoder commandCexistiert unter/opt/bin
  • commandBexistiert im System PATHoder ist sehr verbreitet
  • Diese Befehle schlagen unter der virtuellen Umgebung fehl
  • man braucht eine Vielzahl von verschiedenen virtuellen Umgebungen
ti7
quelle
Vergessen Sie nicht, das in doppelte Anführungszeichen zu setzen, da $(...)sonst Leerzeichen und Tabulatoren in der Ausgabe fehlen.
Eric
"${VAR}"ist genau gleichbedeutend damit, dass "$VAR"Sie keine geschweiften Klammern um Shell-Variablen benötigen, da doppelte Anführungszeichen tatsächlich leistungsfähiger sind. Die Ausnahme ist bei der Verwendung von Modifikatoren zum Beispiel mag"${VAR:-default_value}"
Eric
PATH=$PATH:/opt/binbenötigt korrekte Anführungszeichen, um Pfade mit Leerzeichen und Tabulatoren zu behandeln.
Eric
@ Eric Danke, obwohl du den editButton unter den Posts verwenden kannst , um Änderungen an ihnen vorzuschlagen! Lassen Sie uns außerdem wissen, dass jeder, der wissentlich IFSZeichen hinzufügt , PATHein Terrorist ist, obwohl dies häufig eine Anforderung und wichtig für die Sicherheit ist.
7.
0

Sie sollten mehrere Befehle in einer Zeile verwenden. beispielsweise:

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

Wenn Sie Ihre virtuelle Umgebung in einer Zeile aktivieren, werden andere Befehlszeilen vergessen, und Sie können dies verhindern, indem Sie mehrere Befehle in einer Zeile verwenden. Es hat bei mir funktioniert :)

Ahmadreza Pourghodrat
quelle
0

Als ich venv lernte, erstellte ich ein Skript, um mich daran zu erinnern, wie man es aktiviert.

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

Dies hat den Vorteil, dass die Eingabeaufforderung geändert wird.

Alexx Roche
quelle