2011-11-04 35 views
13

फैब्रिक में, जब मैं अपने .bash_profile फ़ाइल से किसी भी उपनाम 'या फ़ंक्शंस का उपयोग करने का प्रयास करता हूं, तो उन्हें पहचाना नहीं जाता है। उदाहरण के लिए मेरे .bash_profile में alias c='workon django-canada' है, इसलिए जब मैं iTerm या टर्मिनल में c टाइप करता हूं, workon django-canada निष्पादित किया जाता है।कपड़ा मेरी .bash_profile क्यों नहीं देखता है?

मेरे fabfile.py

def test(): 
    local('c') 

शामिल लेकिन जब मैं fab test कोशिश यह मुझ पर इस फेंकता है: [स्थानीय होस्ट] स्थानीय: ग

/bin/sh: c: command not found 

Fatal error: local() encountered an error (return code 127) while executing 'c' 

Aborting. 

अन्य कपड़ा कार्यों ठीक काम करते हैं। क्या मुझे कपड़े में कहीं भी मेरी बैश प्रोफ़ाइल निर्दिष्ट करनी है?

उत्तर

21

संपादित करें - जैसा कि यह पता चला है, यह फैब्रिक 1.4.4 में तय किया गया था। चेंजलॉग से:

[फ़ीचर] #725: स्थानीय स्थानीय खोल के ओवरराइड की अनुमति देने के लिए स्थानीय अपडेट किया गया। मुस्तफा खट्टाब के लिए धन्यवाद।

तो मूल प्रश्न इस तरह निर्धारित किया जाएगा:

def test(): 
    local('c', shell='/bin/bash') 

मैं नीचे मेरी मूल जवाब है, जो केवल कपड़ा संस्करण < 1.4.4 से संबंधित है छोड़ दिया है।


क्योंकि स्थानीय बैश का उपयोग नहीं करता है। आप इसे अपने आउटपुट में स्पष्ट रूप से देख सकते हैं

/bin/sh: c: command not found 

देखें? यह /bin/bash के बजाय /bin/sh का उपयोग कर रहा है। ऐसा इसलिए है क्योंकि फैब्रिक का local कमांड run से आंतरिक रूप से थोड़ा अलग व्यवहार करता है। local कमांड subprocess.Popen पायथन कक्षा के आसपास अनिवार्य रूप से एक रैपर है।

http://docs.python.org/library/subprocess.html#popen-constuctor

और यहाँ अपने समस्या है। Popen डिफ़ॉल्ट /bin/sh पर। यदि आप पॉपन कन्स्ट्रक्टर को स्वयं कॉल कर रहे हैं तो एक अलग खोल निर्दिष्ट करना संभव है, लेकिन आप इसे फैब्रिक के माध्यम से उपयोग कर रहे हैं। और दुर्भाग्य से आपके लिए, फैब्रिक आपको /bin/bash जैसे शेल में पास करने का कोई साधन नहीं देता है।

क्षमा करें कि आपको कोई समाधान नहीं प्रदान करता है, लेकिन इसे आपके प्रश्न का उत्तर देना चाहिए।

संपादित

यहाँ प्रश्न में कोड है, कपड़े के local समारोह operations.py फाइल में परिभाषित से सीधे खींच लिया:

p = subprocess.Popen(cmd_arg, shell=True, stdout=out_stream, 
    stderr=err_stream) 
(stdout, stderr) = p.communicate() 

आप देख सकते हैं, यह निष्पादन योग्य कीवर्ड के लिए कुछ भी में पास नहीं । यह डिफ़ॉल्ट का उपयोग करने का कारण बनता है, जो/bin/sh है। यदि यह बैश का उपयोग करता है, तो यह इस तरह दिखेगा:

p = subprocess.Popen(cmd_arg, shell=True, stdout=out_stream, 
    stderr=err_stream, executable="/bin/bash") 
(stdout, stderr) = p.communicate() 

लेकिन ऐसा नहीं है।यही कारण है कि वे स्थानीय लोगों के लिए प्रलेखन में निम्नलिखित कहते हैं:

लोकल केवल अंतर्निहित पाइथन उपप्रोसेसर मॉड्यूल के उपयोग के चारों ओर एक सुविधाजनक आवरण है जिसे खोल = सही सक्रिय किया गया है। यदि आपको कुछ विशेष करने की ज़रूरत है, तो उपप्रोसेस मॉड्यूल का उपयोग करने पर विचार करें।

+1

लेकिन [फैब्रिक डॉक्स] (http://docs.fabfile.org/en/0.9.0/usage/env.html#shell) कहते हैं: "खोल डिफ़ॉल्ट: **/बिन/बैश ** -l -c मूल्य जब जैसे रन के साथ आदेशों को क्रियान्वित करने खोल आवरण के रूप में प्रयोग किया जाता फार्म में मौजूद में सक्षम होना चाहिए "<आदेश यहाँ जाता है>।" - जैसे डिफ़ॉल्ट बैश के -c विकल्प के रूप में एक कमांड स्ट्रिंग लेता है का उपयोग करता है अपने मूल्य। " –

+1

हाँ, दस्तावेज़ कमांड और सुडो के आदेशों का जिक्र कर रहे हैं। स्थानीय कमांड दृश्यों के पीछे उन लोगों से अलग काम करता है। प्रश्न में कोड दिखाने के लिए मैंने जवाब संपादित किया है। –

+0

स्पष्टीकरण के लिए धन्यवाद। यह बहुत जानकारीपूर्ण –

4

एक वैकल्पिक हल रैप करने के लिए एक पार्टी आदेश के आसपास आपके पास जो कुछ भी आदेश बस है:

@task 
def do_something_local(): 
    local("/bin/bash -l -c 'run my command'") 

आप, इनमें से बहुत कुछ कर एक custom context manager बनाने पर विचार करने की जरूरत है।

+0

धन्यवाद, यह बहुत अच्छा काम करता है। –

0

ऐसा लगता है कि आप स्थानीय रूप से virtualenvwrapper उपयोग करने के लिए कोशिश कर रहे हैं। आप अपने स्थानीय कमांड स्ट्रिंग इस तरह दिखना बनाने की आवश्यकता होगी:

local("/bin/bash -l -c 'workon django-canada && python manage.py runserver'") 

यहाँ तुम्हारा सही मायने में that does that for you in a context manager द्वारा एक उदाहरण है।

संबंधित मुद्दे