How to source virtualenv एक बैश स्क्रिप्ट में सक्रिय


97

आप पायथन virtualenv को सक्रिय करने के लिए एक बैश स्क्रिप्ट कैसे बनाते हैं?

मेरे पास एक निर्देशिका संरचना है जैसे:

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

मैं अपने virtualenv को सक्रिय कर सकता हूं:

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

हालाँकि, बैश स्क्रिप्ट से ऐसा करने से कुछ नहीं होता:

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

मैं क्या गलत कर रहा हूं?


6
जब आप एक शेल स्क्रिप्ट चलाते हैं तो आप वास्तव में एक नया शेल बना रहे होते हैं। उपयोग sourceकरने का बिंदु वर्तमान शेल में कुछ बदलना है। आप virtualenv के अजगर को पूर्ण पथ का उपयोग कर सकते हैं ./env/bin/python
पाब्लो नवारो

@NgureNyaga, नहीं, यह प्रश्न मेरा जैसा नहीं है। वे पूछ रहे हैं कि एक अनियंत्रित स्थान से कैसे स्रोत हो। मैं पहले से ही जानता हूं कि यह कैसे करना है। मैं पूछ रहा हूँ कि कैसे एक कस्टम बैश स्क्रिप्ट के भीतर स्रोत है और स्रोत बनाए रखें।
क्रिनिन

जवाबों:


76

जब आप स्रोत करते हैं, तो आप सक्रिय स्क्रिप्ट को अपने सक्रिय शेल में लोड कर रहे हैं।

जब आप इसे किसी स्क्रिप्ट में करते हैं, तो आप इसे उस शेल में लोड करते हैं, जो आपकी स्क्रिप्ट के समाप्त होने पर बाहर निकलता है और आप अपने मूल, अक्षुण्ण शेल पर वापस आ जाते हैं।

आपका सबसे अच्छा विकल्प यह होगा कि आप इसे किसी फंक्शन में करें

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

या एक उपनाम

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

उम्मीद है की यह मदद करेगा।


विंडोज़ के लिए c: \ tutorial>। \ env \ Scripts \ सक्रिय
अधिकतम 4

5
मुझे इस बात का बिलकुल भी अंदाजा नहीं था कि जब मैं सोर्स कर रहा था तो यह काफी हद तक बेहतर के लिए मेरी बैश स्क्रिप्टिंग को बदल दिया था। धन्यवाद!
रॉबर्ट टाउनले

1
आपके अन्य विचार ने मेरे लिए भी अच्छा काम किया। बस एक ध्यान दें: मुझे इसे काम करने के लिए अपनी .zshrc स्क्रिप्ट (या बैश उपयोगकर्ताओं के लिए .bashrc) में इसे (अन्य नाम abcdef = "स्रोत ... / बिन / सक्रिय") डालना था।
शाहिंस

यदि आप अपने virtualenvs को डिफ़ॉल्ट फ़ोल्डर नाम का उपयोग कर रहे हैं तो यह एक अच्छा समाधान है। मैं फ़ोल्डर में एक से अधिक रेपो रखता था, जो कि वर्चुअन पर एक गड़बड़ बनाता था। मैंने अब इस डिफ़ॉल्ट पर स्विच कर दिया है।
3manuek

3
मैं बैश करने के लिए काफी नया हूँ आदि क्या आप इस उदाहरण का विस्तार कर सकते हैं ताकि यह पूरी स्क्रिप्ट को दिखाए?
AljoSt

54

आपको स्रोत का उपयोग करके बैश स्क्रिप्ट को कॉल करना चाहिए।

यहाँ एक उदाहरण है:

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

अपने शेल पर बस इसे इस तरह से कॉल करें:

> source venv.sh

या जैसा कि @outmind ने सुझाव दिया: (ध्यान दें कि यह zsh के साथ काम नहीं करता है)

> . venv.sh

वहां आप जाते हैं, शेल संकेत आपके प्रॉम्प्ट पर रखा जाएगा।


2
या यहाँ तक कि बस "। venv.sh"
outmind

कोई फर्क नहीं पड़ता कि मैं क्या कोशिश 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

जब मुझे which sourceशेल प्रॉम्प्ट पर टाइप किया जाता है , तब भी मुझे कुछ नहीं मिलता है , फिर भी, source venv3/bin/activateमैं जो उम्मीद करता हूं और वेव खोलता हूं। ...

यह काम क्यों करता है, लेकिन source ./env/bin/activate(उसी #!/bin/bashउपसर्ग के साथ) नहीं करता है? उद्धरणों का उपयोग करने और न करने के बीच क्या अंतर है?
अश्वेत

मुझे उद्धरण के बिना स्क्रिप्ट के अंदर स्रोत का उपयोग करने में कोई समस्या नहीं है। मुझे एक समस्या दिखाई देती है source ./env/bin/activateक्योंकि यह आपके द्वारा चलाए जा रहे पथ के सापेक्ष है? यदि आप स्क्रिप्ट के अंदर निर्देशिका को बदलते हैं तो आप सापेक्ष में जा सकते हैं।
फ्लावियो गार्सिया

13

यद्यपि यह शेल प्रॉम्प्ट में "(.env)" उपसर्ग नहीं जोड़ता है, मैंने पाया कि यह स्क्रिप्ट अपेक्षा के अनुरूप काम करती है।

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

जैसे

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
तकनीकी रूप से आप एक सब-स्पेल का उपयोग कर रहे हैं। यह जरूरी नहीं है कि एक समस्या है, लेकिन आपको ओपी के लिए यह जादू करना चाहिए।
अमीरो

यह काम किया, लेकिन मुझे पहले अपनी "सक्रिय" फ़ाइल की अनुमति देनी थी।
एड्रियन लोपेज

1
यह 2019 में काम करता है! MacOS पर मैं सिर्फ बदलना पड़ा /bin/bashकरने के लिए/usr/bin/env bash
VALEM

2020 में उबंटू 18.04 एडब्ल्यूएस ईसी 2 में काम करता है। मुझे आश्चर्य है कि मैं उसी तर्क का उपयोग करके कैसे निष्क्रिय करूं?
सीएसएफ जूनियर

आप deactivateसबस्क्राइब से exitया Ctrl + d
अलेक्सक्स रोच

10

सोर्सिंग आपके वर्तमान शेल में शेल कमांड चलाता है। जब आप किसी स्क्रिप्ट के अंदर स्रोत जैसे आप ऊपर कर रहे हैं, तो आप उस स्क्रिप्ट के लिए पर्यावरण को प्रभावित कर रहे हैं, लेकिन जब स्क्रिप्ट बाहर निकलती है, तो पर्यावरण में परिवर्तन पूर्ववत होता है, क्योंकि वे प्रभावी रूप से दायरे से बाहर हो गए हैं।

यदि आपका इरादा virtualenv में शेल कमांड चलाने का है, तो आप सक्रिय स्क्रिप्ट को सोर्स करने के बाद अपनी स्क्रिप्ट में ऐसा कर सकते हैं। यदि आपका इरादा वर्चुअनव के अंदर एक शेल के साथ बातचीत करने का है, तो आप अपनी स्क्रिप्ट के अंदर एक उप-शेल को स्पॉन कर सकते हैं जो पर्यावरण को विरासत में देगा।


2

यहां वह स्क्रिप्ट है जिसका मैं अक्सर उपयोग करता हूं। इसे के रूप में चलाएँ$ source script_name

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

activate

1

बाश स्क्रिप्ट के लिए सोर्सिंग क्या है?

  1. यदि आप कई virtualenvs के बीच स्विच करने या जल्दी से एक virtualenv दर्ज करने का इरादा रखते हैं, तो क्या आपने कोशिश की है virtualenvwrapper? यह बहुत सारे बर्तन प्रदान करता है जैसे workon venv, mkvirtualenv venvऔर इसी तरह।

  2. यदि आप केवल कुछ virtualenv में एक अजगर स्क्रिप्ट /path/to/venv/bin/python script.pyचलाते हैं, तो इसे चलाने के लिए उपयोग करें।


दरअसल, मैं workon ...बैश स्क्रिप्ट से कॉल करना चाहूंगा । (क्योंकि मैं हर बार इसके स्टार्टअप पर आगे के सामान को निष्पादित करना चाहता हूं।) इसे काम करने का कोई तरीका नहीं मिल सकता है, हालांकि।
डैनियल बी।

1

आप अपने उपयोग को बेहतर बनाने के लिए एक सब-वेल का उपयोग करके भी ऐसा कर सकते हैं - यहाँ एक व्यावहारिक उदाहरण है:

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

जब यह शैली विशेष रूप से सहायक होती है

  • के एक अलग संस्करण के तहत commandAया commandCमौजूद है/opt/bin
  • commandBसिस्टम में मौजूद है PATHया बहुत आम है
  • ये आदेश virtualenv के अंतर्गत विफल होते हैं
  • एक को अलग-अलग वर्चुअन की जरूरत होती है

दोहरे उद्धरण चिह्नों के लिए मत भूलना $(...)या आप आउटपुट में निहित रिक्त स्थान और टैब गायब कर देंगे।
एरिक

"${VAR}"कड़ाई से बराबर है "$VAR"आपको शेल चर के आसपास घुंघराले कोष्ठक की आवश्यकता नहीं है क्योंकि दोहरे उद्धरण वास्तव में अधिक शक्तिशाली हैं। उदाहरण के लिए जैसे संशोधक का उपयोग करते समय अपवाद"${VAR:-default_value}"
एरिक

PATH=$PATH:/opt/binरिक्त स्थान और टैब के साथ पथ को संभालने के लिए उचित उद्धरण की आवश्यकता है।
एरिक

@ एरिक थैंक्स, हालाँकि आप editपोस्ट के नीचे दिए गए बटन का इस्तेमाल करके उनमें बदलाव के सुझाव दे सकते हैं! इसके अलावा, यह बता दें कि जबकि यह अक्सर सुरक्षा के लिए एक आवश्यकता और महत्वपूर्ण है, जो कोई भी जानबूझकर IFSचार को जोड़ता है PATHवह एक आतंकवादी है।
ti7

0

आपको एक लाइन में कई कमांड का उपयोग करना चाहिए। उदाहरण के लिए:

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

जब आप अपने वर्चुअल वातावरण को एक लाइन में सक्रिय करते हैं, तो मुझे लगता है कि यह अन्य कमांड लाइनों के लिए भूल जाता है और आप एक लाइन में कई कमांड का उपयोग करके इसे रोक सकते हैं। यह मेरे लिए काम :)


0

जब मैं venv सीख रहा था तो मैंने एक स्क्रिप्ट बनाई कि मुझे याद दिलाएं कि इसे कैसे सक्रिय किया जाए।

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

इससे फायदा यह है कि यह प्रॉम्प्ट को बदल देता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.