Bash komut dosyasında virtualenv etkinleştirmesi nasıl kaynaklanır


107

Python virtualenv'i etkinleştirmek için nasıl Bash betiği oluşturursunuz?

Şöyle bir dizin yapım var:

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

Sanal ortamımı şu şekilde etkinleştirebilirim:

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

Ancak aynısını bir Bash betiğinden yapmak hiçbir şey yapmaz:

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

Neyi yanlış yapıyorum?


6
Bir kabuk betiğini çalıştırdığınızda aslında yeni bir kabuk oluşturursunuz. Kullanmanın sourceamacı, mevcut kabuktaki bir şeyi değiştirmektir. Virtualenv'in python'unu tam yolu kullanarak kullanabilirsiniz ./env/bin/python.
Pablo Navarro

@NgureNyaga, Hayır, bu soru benimkiyle aynı değil. Keyfi bir yerden nasıl kaynak sağlanacağını soruyorlar. Bunu nasıl yapacağımı zaten biliyorum. Özel bir bash komut dosyası içinde nasıl kaynak yapılacağını ve kaynağı nasıl koruyacağımı soruyorum.
Cerin

Yanıtlar:


85

Kaynak oluşturduğunuzda, etkinleştirme komut dosyasını etkin kabuğunuza yüklersiniz.

Bunu bir komut dosyasında yaptığınızda, komut dosyanız bittiğinde çıkan kabuğa yüklersiniz ve orijinal, etkinleştirilmemiş kabuğunuza geri dönersiniz.

En iyi seçeneğiniz bunu bir işlevde yapmaktır.

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

veya bir takma ad

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

Bu yardımcı olur umarım.


Windows için c: \ tutorial>. \ env \ Scripts \
activ

7
Kaynak yaptığımda ne olduğu hakkında kesinlikle hiçbir fikrim yoktu Bu, bash betiklememi daha iyi hale getirmek için büyük ölçüde değiştirdi. Teşekkür ederim!
Robert Townley

1
Takma ad fikriniz benim için de iyi çalıştı. Sadece bir not: Çalışması için onu (abcdef = "source ... / bin / activ") .zshrc betiğime (veya bash kullanıcıları için .bashrc) koymam gerekiyordu.
shahins

Varsayılan klasör adını kullanan sanal ortamlarınız varsa bu güzel bir çözümdür. Klasörde birden fazla depom vardı, sanal ortamlarda karışıklık yaratıyordum. Şimdi bu varsayılana geçtim.
3manuek

3
Ben bash vb. Konusunda oldukça yeniyim. Bu örneği tam senaryoyu gösterecek şekilde genişletebilir misiniz?
AljoSt

63

Kaynak kullanarak bash betiğini çağırmalısınız.

İşte bir örnek:

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

Kabuğunuzda şöyle deyin:

> source venv.sh

Veya @outmind'ın önerdiği gibi: (Bunun zsh ile çalışmadığını unutmayın)

> . venv.sh

İşte gidiyorsunuz, kabuk göstergesi komut isteminize yerleştirilecek.


2
hatta sadece ". venv.sh"
2016

Ne 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

Ayrıca which sourcebir kabuk istemine yazdığımda da hiçbir şey alamıyorum , ancak source venv3/bin/activatebeklediğim şeyi yapıyor ve venv'i açıyorum. ...

Bu neden işe yarıyor ama source ./env/bin/activate(aynı #!/bin/bashönek ile) çalışmıyor? Tırnak kullanmakla kullanmamak arasındaki fark nedir?
blacksite

Komut dosyası içindeki kaynağı tırnak işaretleri olmadan kullanmakta sorun yaşamıyorum. İle ilgili bir sorun görüyorum source ./env/bin/activateçünkü bu koştuğunuz yola göre mi? Komut dosyası içindeki dizini değiştirirseniz göreceli olarak gidebilirsiniz.
Flavio Garcia

14

Kabuk istemine "(.env)" önekini eklemese de, bu komut dosyasının beklendiği gibi çalıştığını gördüm.

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

Örneğin

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
teknik olarak bir alt kabuk üretiyorsunuz. Bu mutlaka bir sorun değildir, ancak bunu OP için açıklamalısınız.
richo

Çalıştı, ancak daha önce "etkinleştir" dosyama izin vermem gerekiyordu.
Adrian Lopez

1
Bu 2019'da işe yarıyor! Macos ben sadece değiştirmek zorunda /bin/bashiçin/usr/bin/env bash
Valem

2020'de Ubuntu 18.04 AWS EC2'de çalışıyor. Aynı mantığı kullanarak nasıl devre dışı bırakabilirim?
CSF Junior

Sen deactivateile alt kabuğa gelen exitveya Ctrl + d
Alexx'in Roche

10

Sourcing, mevcut kabuğunuzda kabuk komutlarını çalıştırır. Yukarıda yaptığınız gibi bir komut dosyasının içinde kaynak oluşturduğunuzda, o komut dosyası için ortamı etkilersiniz, ancak komut dosyası çıktığında, ortam değişiklikleri etkin bir şekilde kapsam dışına çıktıkları için geri alınır.

Niyetiniz virtualenv'de kabuk komutlarını çalıştırmaksa, bunu etkinleştirme komut dosyasını sağladıktan sonra komut dosyanızda yapabilirsiniz. Niyetiniz virtualenv içindeki bir kabukla etkileşim kurmaksa, betiğinizin içinde ortamı devralacak bir alt kabuk oluşturabilirsiniz.


3

İşte sık kullandığım senaryo. Olarak çalıştır$ source script_name

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

activate

2

Bash betiğini ne için kaynaklanıyor?

  1. Birden çok sanal ortam arasında geçiş yapmayı veya hızlı bir şekilde bir sanal ortam girmeyi düşünüyorsanız, denediniz virtualenvwrappermi? Sanki utils bir sürü sağlar workon venv, mkvirtualenv venvvb.

  2. Belirli virtualenv'de bir python komut dosyası /path/to/venv/bin/python script.pyçalıştırırsanız , çalıştırmak için kullanın .


Aslında workon ...bir bash betiğinden aramak istiyorum . (Çünkü başlangıçta her seferinde daha sonra başka şeyler yürütmek istiyorum.) Yine de çalışmasını sağlayacak bir yol bulamıyorum.
Daniel B.

1

Bunu, kullanımınızı daha iyi kapsamak için bir alt kabuk kullanarak da yapabilirsiniz - işte pratik bir örnek:

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

Bu tarz özellikle şu durumlarda faydalıdır:

  • farklı bir sürümü commandAveya commandCaltında var/opt/bin
  • commandBsistemde var PATHveya çok yaygın
  • bu komutlar virtualenv altında başarısız olur
  • birinin çeşitli farklı sanal ortamlara ihtiyacı var

Çift tırnak içine almayı unutmayın, $(...)yoksa çıktıda bulunan boşluklar ve sekmeler eksik olacaktır.
Eric

"${VAR}""$VAR"çift ​​tırnaklar aslında daha güçlü olduğundan, kabuk değişkenlerinin etrafında süslü parantezlere ihtiyaç duymamanıza kesinlikle eşdeğerdir . Bunun istisnası, örneğin değiştiricileri kullanırken"${VAR:-default_value}"
Eric

PATH=$PATH:/opt/binboşluklar ve sekmeler içeren yolları işlemek için uygun şekilde alıntı yapılması gerekir.
Eric

@Eric Teşekkürler, yine de editdeğişiklik önermek için yayınların altındaki düğmeyi kullanabilirsiniz ! Ayrıca, güvenlik için genellikle bir gereklilik ve önemli olmasına rağmen, bilerek IFSkarakter ekleyen herkesin PATHterörist olduğunu bilin .
ti7

0

Tek satırda birden çok komut kullanmalısınız. Örneğin:

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

Sanal ortamınızı bir satırda etkinleştirdiğinizde diğer komut satırlarını unuttuğunu düşünüyorum ve bunu tek satırda birden fazla komut kullanarak engelleyebilirsiniz. Benim için çalıştı :)


0

Venv'i öğrenirken, bunu nasıl etkinleştireceğimi hatırlatmak için bir komut dosyası oluşturdum.

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

Bu, bilgi istemini değiştirme avantajına sahiptir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.