मैं अपने चरवाहे में पर्यावरण चर का उपयोग कैसे कर सकता हूं?


34

मेरे पास एक पायथन स्क्रिप्ट है जिसे एक विशेष अजगर स्थापना के साथ चलाने की आवश्यकता है। वहाँ एक तरीका है कि वह के साथ चलाता है एक कबाड़ शिल्प है $FOO/bar/MyCustomPython?

जवाबों:


29

शेबंग लाइन बहुत सीमित है। कई यूनिक्स वेरिएंट (लिनक्स सहित) के तहत, आपके पास केवल दो शब्द हो सकते हैं: एक कमांड और एक तर्क। अक्सर एक लंबी सीमा भी होती है।

सामान्य समाधान एक छोटे शेल आवरण को लिखना है। पायथन लिपि को नाम दें foo.py, और इसके आगे शेल स्क्रिप्ट रखें foo.pyऔर इसे कॉल करें foo। इस दृष्टिकोण को पायथन लिपि पर किसी विशेष शीर्षक की आवश्यकता नहीं है।

#!/bin/sh
exec "$FOO/bar/MyCustomPython" "$0.py" "$@"

एक और लुभावना दृष्टिकोण ऊपर की तरह एक रैपर स्क्रिप्ट लिखना है, और #!/path/to/wrapper/scriptपायथन स्क्रिप्ट पर शेबंग लाइन के रूप में डाल दिया गया है। हालाँकि, अधिकांश इकाइयाँ शेबंग लिपियों की श्रृंखला का समर्थन नहीं करती हैं, इसलिए यह काम नहीं करेगा।

यदि अंदर MyCustomPythonथा $PATH, तो आप envइसे देखने के लिए उपयोग कर सकते हैं :

#!/usr/bin/env MyCustomPython
import 

फिर भी एक और तरीका यह है कि स्क्रिप्ट को एक मान्य शेल स्क्रिप्ट (जो अपने आप में सही पायथन इंटरप्रेटर लोड करता है) और लक्ष्य भाषा (यहां पायथन) में एक मान्य स्क्रिप्ट दोनों को लोड करने की व्यवस्था है। इसके लिए आवश्यक है कि आप अपनी लक्षित भाषा के लिए इस तरह की दोहरी भाषा की स्क्रिप्ट लिखने का तरीका खोजें। पर्ल में, इसे इस रूप में जाना जाता है if $running_under_some_shell

#!/bin/sh
eval 'exec "$FOO/bar/MyCustomPerl" -wS $0 ${1+"$@"}'
    if $running_under_some_shell;
use 

पायथन में समान प्रभाव को प्राप्त करने का एक तरीका यह है। खोल में, "true"है trueउपयोगिता है, जो अपने तर्कों (दो एकल-चरित्र तार पर ध्यान नहीं देता :और ') और एक सच्चे मान देता है। पायथन में, "true"एक स्ट्रिंग है जो एक बूलियन के रूप में व्याख्या करने पर सच है, इसलिए यह एक ifनिर्देश है जो हमेशा सच होता है और एक स्ट्रिंग शाब्दिक निष्पादित करता है।

#!/bin/sh
if "true" : '''\'
then
exec "$FOO/bar/MyCustomPython" "$0" "$@"
exit 127
fi
'''
import 

रोसेटा कोड में कई अन्य भाषाओं में ऐसी दोहरी-भाषा स्क्रिप्ट हैं।


1
@ क्रिस: सब कुछ एकल उद्धरण के अंदर है। कृपया समझाएँ ...
स्टेफेन जिमेनेज़

1
आप एक खूनी जादूगर हैं ... यह बहुत अच्छा है। मैंने PYTHONPATHएक एनजीआई स्क्रिप्ट के लिए एक गैर-मानक स्थान से मॉड्यूल लोड करने के लिए एनवी चर को संपादित करने के लिए इसका उपयोग किया, जिस सिस्टम पर मुझे रूट एक्सेस नहीं था। जीवन रक्षक। एक बार फिर धन्यवाद।
wspurgin 21

12

शेबांग लाइनें चर विस्तार से नहीं गुजरती हैं, इसलिए आप इसका उपयोग नहीं कर सकते हैं $FOO/MyCustomPythonक्योंकि यह एक निष्पादन योग्य नाम के लिए डॉलर-FOO -... की खोज करेगा।

एक विकल्प के रूप में एक शेल स्क्रिप्ट के लिए दुभाषिया के रूप में आपका शेबंग पॉइंट होना चाहिए, और यह शेल स्क्रिप्ट फिर सही का पता लगाने और इसे निष्पादित करने के लिए पर्यावरण चर का उपयोग कर सकती है।

उदाहरण: निम्नलिखित सामग्री के साथ (या किसी अन्य निर्देशिका में ) mypython.shस्क्रिप्ट बनाएँ :/usr/local/bin$PATH

#! /bin/sh
PYTHON="$FOO/bar/MyCustomPython"
exec "$PYTHON" "$@"

तब आप इस शेबंग लाइन का उपयोग एक पायथन स्क्रिप्ट के माध्यम MyCustomPythonसे निष्पादित करने के लिए कर सकते हैं mypython.sh:

#!/usr/bin/env mypython.sh

6
उपयोग $python, नहीं $PYTHON- सम्मेलन द्वारा, हम पर्यावरण चर (PAGER, EDITOR, SHELL ... $PYTHONको अपनी स्क्रिप्ट में पर्यावरण चर नहीं है) और आंतरिक शेल चर (BASH_VERSION, RANDOM, ...) को कैपिटल करते हैं। अन्य सभी चर नामों में कम से कम एक लोअरकेस अक्षर होना चाहिए। यह कन्वेंशन गलती से पर्यावरण और आंतरिक चर को ओवरराइड करने से बचता है। इसके अलावा, अपनी स्क्रिप्ट के लिए एक्सटेंशन का उपयोग न करें। लिपियाँ नई कमांड्स को परिभाषित करती हैं जिन्हें आप चला सकते हैं, और कमांड्स को आमतौर पर एक्सटेंशन नहीं दिया जाता है।
क्रिस डाउन

4

आप कस्टम अजगर स्थापना के लिए या तो निरपेक्ष पथ का उपयोग कर सकते हैं, या आप इसे अपने $PATHउपयोग में ला सकते हैं #!/usr/bin/env [command]। अन्यथा, इसके लिए एक आवरण लिखें और execप्रक्रिया छवि को बदलने के लिए उपयोग करें, उदाहरण के लिए:

#!/bin/bash
exec "$ENV/python" "$@"

3

सबसे पहले, यह निर्धारित करें कि पायथन का आपका संस्करण पहले से स्थापित मानक पायथन से कैसे भिन्न है (उदाहरण के लिए, एक अतिरिक्त मॉड्यूल) और फिर कार्यक्रम की शुरुआत में 'स्विच' कैसे पायथन कहा जाता है:

#!/usr/bin/python
import os
import sys
try:
    import MyCustomModule
except ImportError:
    # only need to use expandvar if you know the string below has an envvar
    custprog = os.path.expandvar("$FOO/bar/MyCustomPython")
    os.execv(custprog, sys.argv) # call alternate python with the same arguments
    raise SystemExit('could not call %s' % custprog)
# if we get here, then we have the correct python interpreter

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


0

आप बदल सकते हैं तो $FOOमें $FOO/bar/MyCustomPythonठोस पथ विकल्पों के साथ, आप बता सकते envकुटिया लाइन जहां सीधे एक कस्टम सेट करके अपने कस्टम पायथन संस्करण को देखने के लिए PATHउस में।

#!/usr/bin/env PATH="/path1/to/MyCustomPython:/path2/to/MyCustomPython" python

संपादित करें : केवल PATH मान असाइनमेंट के आसपास उद्धरण के बिना काम करने लगता है:

#!/usr/bin/env PATH=/path1/to/MyCustomPython:/path2/to/MyCustomPython python

5
खबरदार कि यह सभी यूनिक्स वेरिएंट (जैसे लिनक्स पर नहीं) पर काम नहीं करता है। और आप रास्ते से सभी मौजूदा निर्देशिकाओं को हटा रहे हैं, जिससे लाइन के नीचे समस्या होने की संभावना है।
गिल्स एसओ- बुराई को रोकना '

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