Jak utworzyć skrypt Bash, aby aktywować virtualenv w języku Python?
Mam strukturę katalogów taką jak:
.env
bin
activate
...other virtualenv files...
src
shell.sh
...my code...
Mogę aktywować virtualenv poprzez:
user@localhost:src$ . ../.env/bin/activate
(.env)user@localhost:src$
Jednak zrobienie tego samego ze skryptu Bash nic nie robi:
user@localhost:src$ cat shell.sh
#!/bin/bash
. ../.env/bin/activate
user@localhost:src$ ./shell.sh
user@localhost:src$
Co ja robię źle?
python
bash
virtualenv
Cerin
źródło
źródło
source
jest zmiana czegoś w bieżącej powłoce. Możesz użyć Pythona virtualenv, używając pełnej ścieżki./env/bin/python
.Odpowiedzi:
Kiedy pobierasz źródło, ładujesz skrypt aktywacyjny do aktywnej powłoki.
Kiedy robisz to w skrypcie, ładujesz go do tej powłoki, która kończy pracę po zakończeniu skryptu i wracasz do oryginalnej, nieaktywowanej powłoki.
Najlepszym rozwiązaniem byłoby zrobienie tego w funkcji
activate () { . ../.env/bin/activate }
lub alias
alias activate=". ../.env/bin/activate"
Mam nadzieję że to pomoże.
źródło
Powinieneś wywołać skrypt bash używając source.
Oto przykład:
#!/bin/bash # Let's call this script venv.sh source "<absolute_path_recommended_here>/.env/bin/activate"
Na swojej powłoce po prostu nazwij to tak:
> source venv.sh
Lub jak zasugerował @outmind: (Zauważ, że to nie działa z zsh)
> . venv.sh
Proszę, wskazanie powłoki zostanie umieszczone w twoim znaku zachęty.
źródło
source "/home/surest/Desktop/testservers/TEST_VENV/venv3/bin/activate"
daje to :/home/surest/Desktop/testservers/TEST_VENV/py3.sh: 10: /home/surest/Desktop/testservers/TEST_VENV/py3.sh: source: not found
which source
wsource venv3/bin/activate
zachęcie powłoki, ale robi to, czego się spodziewam i otwieram venv. ...source ./env/bin/activate
(z tym samym#!/bin/bash
prefiksem) nie? Jaka jest różnica między używaniem cudzysłowów a nie?source ./env/bin/activate
ponieważ jest to zależne od ścieżki, którą biegniesz, prawda? Jeśli zmienisz katalog wewnątrz skryptu, możesz przejść do względnej.Chociaż nie dodaje przedrostka „(.env)” do znaku zachęty powłoki, stwierdziłem, że ten skrypt działa zgodnie z oczekiwaniami.
#!/bin/bash script_dir=`dirname $0` cd $script_dir /bin/bash -c ". ../.env/bin/activate; exec /bin/bash -i"
na przykład
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
źródło
/bin/bash
na/usr/bin/env bash
deactivate
z podpowłoki za pomocąexit
lub Ctrl + dSourcing uruchamia polecenia powłoki w bieżącej powłoce. Kiedy pozyskujesz źródło wewnątrz skryptu, tak jak robisz powyżej, wpływasz na środowisko tego skryptu, ale kiedy skrypt kończy pracę, zmiany środowiska są cofane, ponieważ faktycznie wyszły poza zakres.
Jeśli zamierzasz uruchamiać polecenia powłoki w virtualenv, możesz to zrobić w swoim skrypcie po pobraniu skryptu aktywacyjnego. Jeśli twoim zamiarem jest interakcja z powłoką wewnątrz virtualenv, możesz stworzyć podpowłokę wewnątrz swojego skryptu, która odziedziczy środowisko.
źródło
Oto skrypt, którego często używam. Uruchom to jako
$ source script_name
#!/bin/bash -x PWD=`pwd` /usr/local/bin/virtualenv --python=python3 venv echo $PWD activate () { . $PWD/venv/bin/activate } activate
źródło
Do czego służy pozyskiwanie skryptu bash?
Jeśli zamierzasz przełączać się między wieloma virtualenvami lub szybko wprowadzać jeden virtualenv, czy próbowałeś
virtualenvwrapper
? Zapewnia dużo utils jakworkon venv
,mkvirtualenv venv
i tak dalej.Jeśli po prostu uruchamiasz skrypt Pythona w pewnym virtualenv, użyj go,
/path/to/venv/bin/python script.py
aby go uruchomić.źródło
workon ...
ze skryptu bash. (Ponieważ chcę wykonać kolejne rzeczy później za każdym razem podczas jego uruchamiania). Nie mogę jednak znaleźć sposobu, aby to zadziałało.Możesz to również zrobić za pomocą podpowłoki, aby lepiej ograniczyć użycie - oto praktyczny przykład:
#!/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"
Ten styl jest szczególnie pomocny, gdy
commandA
lubcommandC
istnieje w ramach/opt/bin
commandB
istnieje w systemiePATH
lub jest bardzo powszechneźródło
$(...)
lub w wynikach będzie brakować spacji i tabulatorów."${VAR}"
jest ściśle równoważne z"$VAR"
tym, że nie potrzebujesz nawiasów klamrowych wokół zmiennych powłoki, ponieważ podwójne cudzysłowy są w rzeczywistości potężniejsze. Wyjątkiem jest użycie modyfikatorów, takich jak na przykład"${VAR:-default_value}"
PATH=$PATH:/opt/bin
wymaga odpowiedniego cytowania do obsługi ścieżek ze spacjami i tabulatorami.edit
przycisku pod postami, aby zasugerować zmiany! Co więcej, niech będzie wiadomo, że chociaż jest to często wymóg i ważny dla bezpieczeństwa, każdy, kto świadomie dodajeIFS
znaki,PATH
jest terrorystą.Powinieneś użyć wielu poleceń w jednej linii. na przykład:
os.system(". Projects/virenv/bin/activate && python Projects/virenv/django-project/manage.py runserver")
Kiedy aktywujesz swoje wirtualne środowisko w jednej linii, myślę, że zapomina o innych wierszach poleceń i możesz temu zapobiec, używając wielu poleceń w jednym wierszu. U mnie zadziałało :)
źródło
Kiedy uczyłem się venv, stworzyłem skrypt, który przypomina mi, jak go aktywować.
#!/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
Ma to tę zaletę, że zmienia monit.
źródło