लोग पायथन लिपि की पहली पंक्ति पर #! / Usr / bin / env python shebang क्यों लिखते हैं?


1046

यह मुझे लगता है कि फ़ाइलों को उस लाइन के बिना ही चलाते हैं।


1
नीचे दिए गए जवाब में कहा गया है कि यह सिर्फ एक टिप्पणी लाइन है। हमेशा ऐसा नहीं होता। मेरे पास "हैलो, वर्ल्ड!" CGI स्क्रिप्ट (.py) जो केवल #!/usr/bin/env pythonशीर्ष पर वेबपृष्ठ को चलाएगी और प्रदर्शित करेगी ।
चाकोते


वे चल सकते हैं, लेकिन इच्छित वातावरण में नहीं
निकोलस हैमिल्टन

18
मैंने 7 साल में इस पोस्ट को बहुत बार देखा है क्योंकि मैं कभी-कभी env हैशबैंग को भूल जाता हूं। कॉपी पास्ता :)
BugHunterUK

जवाबों:


1082

यदि आपके पास पायथन के कई संस्करण स्थापित हैं, तो /usr/bin/envयह सुनिश्चित करेगा कि इस्तेमाल किया जाने वाला दुभाषिया आपके पर्यावरण पर पहला है $PATH। विकल्प हार्डकोड की तरह होगा #!/usr/bin/python; यह ठीक है, लेकिन कम लचीला है।

यूनिक्स में, एक निष्पादन योग्य फ़ाइल जिसकी व्याख्या की जा सकती है, यह इंगित कर सकती है कि #!पहली पंक्ति की शुरुआत में, दुभाषिया (और किसी भी झंडे की आवश्यकता हो सकती है) का उपयोग करके क्या दुभाषिया का उपयोग किया जा सकता है।

आप अन्य प्लेटफार्मों के बारे में बात कर रहे हैं, ज़ाहिर है, इस नियम लागू नहीं होता है (लेकिन है कि "कुटिया लाइन" कोई बुराई करता है, और मदद करता है, तो आप कभी भी एक मंच करने के लिए है कि स्क्रिप्ट की प्रतिलिपि बनाएगा साथ इस तरह के लिनक्स, मैक के रूप में एक यूनिक्स आधार है, , आदि)।


267
बस जोड़ने के लिए: यह तब लागू होता है जब आप इसे यूनिक्स में chmod +x myscript.pyचलाकर इसे निष्पादन योग्य ( ) बना देते हैं और फिर इसे सीधे चलाते हैं: ./myscript.pyबजाय इसके python myscript.py
क्रेग मैकक्वीन

28
उपयोग करने envसे अधिकतम लचीलापन मिलता है कि उपयोगकर्ता PATH को बदलकर उपयोग करने के लिए दुभाषिया का चयन कर सकता है। हालांकि इस लचीलेपन की आवश्यकता नहीं होती है और नकारात्मक पक्ष यह है कि उदाहरण के लिए लिनक्स प्रक्रिया में नाम के लिए स्क्रिप्ट नाम का उपयोग नहीं कर सकता है psऔर "अजगर" का संदर्भ देता है । जब उदाहरण के लिए डिस्ट्रोस के लिए अजगर क्षुधा की पैकेजिंग मैं उपयोग नहीं करने की सलाह दूंगा env
पिक्सेलबीट

9
pyलांचर विंडोज पर शेबंग लाइन का उपयोग कर सकता है। इसे पायथन 3.3 में शामिल किया गया है या इसे स्वतंत्र रूप से स्थापित किया जा सकता है
jfs

6
चेतावनी का एक महत्वपूर्ण शब्द, एनव का वापसी मूल्य अंततः समाप्त हो रहा है। यदि आप अल्पकालिक प्रक्रियाओं को चला रहे हैं तो आपको प्रभावित करने की संभावना नहीं है। हालाँकि, मैंने /usr/bin/env: Key has expiredकई घंटों के बाद संदेश के साथ मरने की प्रक्रिया की है ।
मालावरडेयर

4
@malaverdiere क्या आप ऐसे किसी भी संसाधन से जुड़ सकते हैं जो इस समाप्ति व्यवहार की व्याख्या करता है? मैं उन्हें नहीं ढूँढ सकता।
माइकल

266

इसे शबंग रेखा कहा जाता है । जैसा कि विकिपीडिया प्रविष्टि बताती है :

कंप्यूटिंग में, एक शेबबैंग (जिसे हैशबैंग, हैशप्लिंग, पाउंड बैंग या क्रंचबैंग भी कहा जाता है) वर्णों को संदर्भित करता है # #! " जब वे एक पाठ फ़ाइल की पहली पंक्ति के रूप में दुभाषिया निर्देशन में पहले दो अक्षर होते हैं। यूनिक्स जैसी ऑपरेटिंग सिस्टम में, प्रोग्राम लोडर इन दोनों पात्रों की उपस्थिति को एक संकेत के रूप में लेता है कि फ़ाइल एक स्क्रिप्ट है, और फ़ाइल में पहली पंक्ति के बाकी द्वारा निर्दिष्ट दुभाषिया का उपयोग करके उस स्क्रिप्ट को निष्पादित करने का प्रयास करता है।

यूनिक्स एफएक्यू प्रविष्टि भी देखें ।

यहां तक ​​कि विंडोज पर, जहां शेबबैंग लाइन को चलाने के लिए दुभाषिया निर्धारित नहीं करता है, आप दुभाषिया को शेबंग लाइन पर निर्दिष्ट करके विकल्प पास कर सकते हैं। मुझे एक-बंद स्क्रिप्ट (जैसे कि मैं एसओ पर सवालों के जवाब देते समय लिखता हूं) में एक सामान्य शेबंग लाइन रखने के लिए उपयोगी लगता है, इसलिए मैं जल्दी से उन्हें विंडोज और आर्कलिन दोनों पर परीक्षण कर सकता हूं

Env उपयोगिता आप रास्ते पर एक आदेश को लागू करने की अनुमति देता है:

पहला शेष तर्क प्रोग्राम नाम को निर्दिष्ट करने के लिए निर्दिष्ट करता है; इसे PATHपर्यावरण चर के अनुसार खोजा जाता है । किसी भी शेष तर्कों को उस कार्यक्रम के तर्क के रूप में पारित किया जाता है।


30
Google के साथ खोजना आसान है - यदि कोई कीवर्ड जानता है ("शेबंग लाइन" आवश्यक है)।
अराफंगियन

14
दरअसल, यह स्पष्टीकरण Google के साथ मेरे द्वारा जांचे गए अन्य संदर्भों की तुलना में स्पष्ट है। हर संभावित उपयोग को संबोधित करने वाले एक पूरे मैनुअल को पढ़ने के बजाय, प्रश्न को लक्षित करते हुए 1 पैरा स्पष्टीकरण प्राप्त करना हमेशा अच्छा होता है।
सैम गोल्डबर्ग

1
@ प्रारूप आपको शायद यह प्रश्न उपयोगी लगेगा । TL; DR: symbolhound.com
ulidtko

@ulidtko: दिलचस्प खोज इंजन, एक उत्तर लिखने पर विचार करें ताकि जॉन गार्सिया के प्रश्न का बेहतर उत्तर हो।
अरफांगियन

1
"यहां तक ​​कि विंडोज पर, जहां शेबबैंग लाइन को चलाने के लिए दुभाषिया निर्धारित नहीं करता है, आप दुभाषिया के लिए उन्हें शेबंग लाइन पर निर्दिष्ट करके विकल्प पास कर सकते हैं।" वह तो झूठा है; अगर ऐसा होता है, तो यह इसलिए है क्योंकि दुभाषिया खुद ही शेबंग लाइन का प्रसंस्करण कर रहा है। यदि दुभाषिया को शेबंग लाइनों के लिए कोई विशेष मान्यता नहीं है, तो ऐसी कोई बात नहीं होती है। Windows शेबंग लाइनों के साथ कुछ भी नहीं करता है। "इस मामले में आप जो वर्णन कर रहे हैं वह अजगर लांचर है: python.org/dev/peps/pep-0397
कज़

154

अन्य उत्तरों पर थोड़ा विस्तार करते हुए, यहाँ थोड़ा सा उदाहरण दिया गया है कि आपकी कमांड लाइन की /usr/bin/envपटकथाएँ शेबंग लाइनों के अनाधिकृत उपयोग से कैसे मुसीबत में पड़ सकती हैं :

$ /usr/local/bin/python -V
Python 2.6.4
$ /usr/bin/python -V
Python 2.5.1
$ cat my_script.py 
#!/usr/bin/env python
import json
print "hello, json"
$ PATH=/usr/local/bin:/usr/bin
$ ./my_script.py 
hello, json
$ PATH=/usr/bin:/usr/local/bin
$ ./my_script.py 
Traceback (most recent call last):
  File "./my_script.py", line 2, in <module>
    import json
ImportError: No module named json

पायथन 2.5 में json मॉड्यूल मौजूद नहीं है।

उस तरह की समस्या से बचाव करने का एक तरीका यह है कि संस्करण वाले पायथन कमांड नामों का उपयोग किया जाए जो आमतौर पर अधिकांश अजगर के साथ स्थापित होते हैं:

$ cat my_script.py 
#!/usr/bin/env python2.6
import json
print "hello, json"

यदि आपको केवल पायथन 2.x और पायथन 3.x के बीच अंतर करने की आवश्यकता है, तो हाल ही में पायथन 3 की रिलीज़ भी एक python3नाम प्रदान करती है :

$ cat my_script.py 
#!/usr/bin/env python3
import json
print("hello, json")

27
हम्म, यही नहीं मैं उस पोस्ट से बाहर निकला।
ग्लेन जैकमैन

1
स्थानीय और वैश्विक के बीच अंतर। यदि which pythonरिटर्न /usr/bin/python, एक स्थानीय निर्देशिका पथ कठिन कोडित किया जा सकता है #!/usr/bin/python:। लेकिन यह कम लचीला है #!/usr/bin/env pythonजिसके पास एक वैश्विक अनुप्रयोग है।
noobninja

85

अजगर लिपि को चलाने के लिए, हमें शेल को तीन बातें बतानी होंगी:

  1. वह फाइल एक स्क्रिप्ट है
  2. हम कौन सा दुभाषिया स्क्रिप्ट को निष्पादित करना चाहते हैं
  3. उक्त व्याख्याकार का मार्ग

शेबंग #!पूरा करता है (1.)। शेबबैंग शुरू होता है #क्योंकि #कई स्क्रिप्टिंग भाषाओं में चरित्र एक टिप्पणी मार्कर है। शेलबैंग लाइन की सामग्री को इसलिए दुभाषिया द्वारा स्वचालित रूप से अनदेखा किया जाता है।

envआदेश सिद्ध (2.) और (3)। "ग्रेविटी" को उद्धृत करने के लिए,

envकमांड का एक सामान्य उपयोग दुभाषियों को लॉन्च करना है, इस तथ्य का उपयोग करके कि एनवी उस लॉन्च के लिए $ PATH की खोज करेगा, जिसे लॉन्च करने के लिए कहा गया है। चूंकि शेलबैंग लाइन को निर्दिष्ट करने के लिए एक पूर्ण मार्ग की आवश्यकता होती है, और चूंकि विभिन्न दुभाषियों (पर्ल, बैश, पाइथन) का स्थान बहुत भिन्न हो सकता है, इसका उपयोग करना आम है:

#!/usr/bin/env perl  इसके बजाय यह अनुमान लगाने की कोशिश कर रहा है कि यह / बिन / पर्ल, / usr / बिन / पर्ल, / usr / स्थानीय / बिन / पर्ल, / usr / स्थानीय / pkg / पर्ल, / fileserver / usr / बिन / पर्ल, या / घर है / उपयोगकर्ता के सिस्टम पर MrDaniel / usr / bin / perl ...

दूसरी ओर, env लगभग हमेशा / usr / bin / env में होता है। (ऐसे मामलों को छोड़कर जब ऐसा नहीं होता है; कुछ सिस्टम / बिन / env का उपयोग कर सकते हैं, लेकिन यह एक काफी दुर्लभ घटना है और केवल गैर-लिनक्स सिस्टम पर होता है।)


1
"घबराहट" कहाँ?
पेसियर

44

शायद आपका प्रश्न इस अर्थ में है:

यदि आप उपयोग करना चाहते हैं: $python myscript.py

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

लेकिन अगर आप उपयोग करने का इरादा रखते हैं: $./myscript.py

इसे एक सामान्य प्रोग्राम या बैश स्क्रिप्ट की तरह सीधे कॉल करना, आपको उस सिस्टम को निर्दिष्ट करने के लिए उस लाइन को लिखने की आवश्यकता है जिसे प्रोग्राम इसे चलाने के लिए उपयोग करता है, (और इसके साथ निष्पादन योग्य भी बनाता है chmod 755)


या आप python3 myscript.py
vijay

44

execलिनक्स कर्नेल का सिस्टम कॉल देशी #!रूप से शेबांग ( ) को समझता है

जब आप बैश पर करते हैं:

./something

लिनक्स पर, यह execसिस्टम कॉल को पथ के साथ कॉल करता है ./something

कर्नेल की इस लाइन को पास की गई फ़ाइल पर कॉल किया जाता है exec: https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_script.c#L25

if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!'))

यह फ़ाइल के पहले बाइट्स को पढ़ता है, और उनकी तुलना करता है #!

यदि तुलना सही है, तो बाकी लाइन को लिनक्स कर्नेल द्वारा पार्स किया जाता है, जो पहले तर्क के रूप में execपथ /usr/bin/env pythonऔर वर्तमान फ़ाइल के साथ एक और कॉल करता है:

/usr/bin/env python /path/to/script.py

और यह किसी भी स्क्रिप्टिंग भाषा के लिए काम करता है #जो एक टिप्पणी चरित्र के रूप में उपयोग करता है ।

और हाँ, आप एक अनंत लूप बना सकते हैं:

printf '#!/a\n' | sudo tee /a
sudo chmod +x /a
/a

बैश त्रुटि को पहचानता है:

-bash: /a: /a: bad interpreter: Too many levels of symbolic links

#! बस मानव पठनीय होता है, लेकिन इसकी आवश्यकता नहीं है।

यदि फ़ाइल अलग-अलग बाइट्स के साथ शुरू होती है, तो execसिस्टम कॉल एक अलग हैंडलर का उपयोग करेगा। अन्य सबसे महत्वपूर्ण अंतर्निहित हैंडलर ELF निष्पादन योग्य फ़ाइलों के लिए है: https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_elf.c#L1305 जो बाइट्स की जांच करता है 7f 45 4c 46(जो मानव भी होता है के लिए पठनीय .ELF)। आइए पुष्टि करते हैं कि 4 पहले बाइट्स को पढ़कर /bin/ls, जो एक ईएलएफ निष्पादन योग्य है:

head -c 4 "$(which ls)" | hd 

उत्पादन:

00000000  7f 45 4c 46                                       |.ELF|
00000004                                                                 

इसलिए जब कर्नेल उन बाइट्स को देखता है, तो वह ईएलएफ फ़ाइल लेता है, इसे सही ढंग से मेमोरी में डालता है, और इसके साथ एक नई प्रक्रिया शुरू करता है। यह भी देखें: कर्नेल को लिनक्स के तहत चलने वाली एक निष्पादन योग्य बाइनरी फ़ाइल कैसे मिलती है?

अंत में, आप binfmt_miscतंत्र के साथ अपने खुद के शेबंग हैंडलर जोड़ सकते हैं । उदाहरण के लिए, आप फ़ाइलों के लिए.jar एक कस्टम हैंडलर जोड़ सकते हैं । यह तंत्र फ़ाइल एक्सटेंशन द्वारा हैंडलर का भी समर्थन करता है। एक अन्य आवेदन QEMU के साथ एक अलग वास्तुकला के पारदर्शी रूप से चलाने के लिए है ।

मुझे नहीं लगता कि POSIX हालांकि शगुन को निर्दिष्ट करता है: https://unix.stackexchange.com/a/346214/32558 , हालांकि यह तर्क वर्गों पर उल्लेख करता है, और "अगर निष्पादन योग्य स्क्रिप्ट सिस्टम द्वारा समर्थित हैं तो कुछ हो सकता है" हो "। macOS और FreeBSD भी इसे लागू करते हैं।

PATH खोज प्रेरणा

इसी तरह, शबंगों के अस्तित्व के लिए एक बड़ी प्रेरणा यह तथ्य है कि लिनक्स में, हम अक्सर PATHबस से कमांड चलाना चाहते हैं :

basename-of-command

के बजाय:

/full/path/to/basename-of-command

लेकिन फिर, शेबबैंग तंत्र के बिना, लिनक्स कैसे जानता होगा कि प्रत्येक प्रकार की फ़ाइल कैसे लॉन्च की जाए?

कमांड में एक्सटेंशन को हार्डकोड करना:

 basename-of-command.py

या हर दुभाषिया पर पथ खोज लागू करना:

python basename-of-command

एक संभावना होगी, लेकिन यह प्रमुख समस्या है कि अगर हम कभी भी किसी अन्य भाषा में कमांड को रिफैक्ट करने का निर्णय लेते हैं तो सब कुछ टूट जाता है।

शेबंग इस समस्या को खूबसूरती से हल करते हैं।


39

तकनीकी रूप से, पायथन में, यह केवल एक टिप्पणी लाइन है।

यह पंक्ति केवल तभी उपयोग की जाती है यदि आप शेल से कमांड (कमांड लाइन से) स्क्रिप्ट चलाते हैं । यह " शेबंग " के रूप में जाना जाता है, और इसका उपयोग विभिन्न स्थितियों में किया जाता है, न कि केवल पाइथन लिपियों के साथ।

यहां, यह शेल को पायथन के एक विशिष्ट संस्करण को शुरू करने का निर्देश देता है (शेष फाइल की देखभाल के लिए।


शेबंग एक यूनिक्स अवधारणा है। यह उल्लेख के लायक हो सकता है कि यह विंडोज पर भी काम करता है यदि आपने पायथन लॉन्चर स्थापित किया हैpy.exe । यह एक मानक पायथन इंस्टॉलेशन का हिस्सा है।
फ्लोरिसला

38

ऐसा करने का मुख्य कारण ऑपरेटिंग सिस्टम वातावरण में स्क्रिप्ट को पोर्टेबल बनाना है।

मिंगव के तहत उदाहरण के लिए, अजगर लिपियों का उपयोग करें:

#!/c/python3k/python 

और GNU / Linux वितरण के तहत यह या तो है:

#!/usr/local/bin/python 

या

#!/usr/bin/python

और सभी (ओएस / एक्स) के सर्वश्रेष्ठ वाणिज्यिक यूनिक्स स्व / एचडब्ल्यू सिस्टम के तहत, यह है:

#!/Applications/MacPython 2.5/python

या FreeBSD पर:

#!/usr/local/bin/python

हालाँकि ये सभी अंतर स्क्रिप्ट का उपयोग करके सभी को पोर्टेबल बना सकते हैं:

#!/usr/bin/env python

2
MacOSX के तहत, यह भी है /usr/bin/python। लिनक्स के तहत, सिस्टम द्वारा स्थापित पायथन भी लगभग निश्चित रूप से है /usr/bin/python(मैंने कभी कुछ और नहीं देखा है और इसका कोई मतलब नहीं होगा)। ध्यान दें कि ऐसी प्रणालियाँ हो सकती हैं जिनके पास नहीं है /usr/bin/env
अल्बर्ट

1
आप पर OSX कर रहे हैं और Homebrew का उपयोग करें और अपने डिफ़ॉल्ट इंस्टॉलेशन निर्देशों का पालन करें, तो यह # के तहत हो जाएगा / usr / स्थानीय / bin / अजगर!
विल

@ जीन पॉल पॉलडरोन: साज़ का जवाब नीचे देखें।
pydsigner

2018 वर्ष के लिए अपडेट: नंगे pythonवह पोर्टेबल नहीं है, यह डिफॉल्ट डिफॉल्ट पायथन दुभाषिया है। आर्क लिनक्स लंबे समय तक पायथन 3 में डिफॉल्ट करता है और वितरण इसके बारे में भी सोच रहे हैं क्योंकि पायथन 2 केवल 2020 तक समर्थित है।
mati865

22

यह संभवतः एक बात पर जोर देने के लिए समझ में आता है जो सबसे ज्यादा याद किया गया है, जो तत्काल समझ को रोक सकता है। जब आप pythonटर्मिनल में टाइप करते हैं तो आप आम तौर पर एक पूर्ण पथ प्रदान नहीं करते हैं। इसके बजाय, निष्पादन योग्य PATHपर्यावरण चर में देखा जाता है। बदले में, जब आप सीधे पायथन प्रोग्राम को निष्पादित करना चाहते हैं, तो /path/to/app.py, किसी को शेल को यह बताना होगा कि इंटरप्रेटर का उपयोग क्या करना है ( हैशबैंग के माध्यम से , जो अन्य योगदानकर्ता ऊपर बता रहे हैं)।

हैशबैंग एक दुभाषिया के लिए पूर्ण पथ की अपेक्षा करता है। इस प्रकार सीधे अपने पायथन प्रोग्राम को चलाने के लिए आपको पायथन बाइनरी को पूर्ण पथ प्रदान करना होगा जो कि काफी भिन्न होता है, विशेष रूप से वर्चुअन के उपयोग को देखते हुए । पोर्टेबिलिटी को संबोधित करने के लिए चाल के साथ /usr/bin/envप्रयोग किया जाता है। उत्तरार्द्ध मूल रूप से पर्यावरण को बदलने और इसमें एक कमांड चलाने का इरादा है। जब कोई परिवर्तन नहीं किया जाता है तो यह वर्तमान वातावरण में कमांड चलाता है, जो प्रभावी रूप से उसी PATHलुकअप में परिणाम करता है जो चाल करता है।

यूनिक्स स्टेक्सएक्सचेंज से स्रोत


14

यह एक शेल कन्वेंशन है जो शेल को बताता है कि कौन सा प्रोग्राम स्क्रिप्ट को निष्पादित कर सकता है।

#! / usr / bin / env अजगर

पायथन बाइनरी के लिए एक मार्ग का समाधान करता है।


12

यह अनुशंसित तरीका है, प्रलेखन में प्रस्तावित:

2.2.2। निष्पादन योग्य अजगर लिपियों

BSD'ish Unix सिस्टम पर, पाइथन लिपियों को सीधे निष्पादन योग्य बनाया जा सकता है, जैसे शेल स्क्रिप्ट, लाइन लगाकर

#! /usr/bin/env python3.2

से http://docs.python.org/py3k/tutorial/interpreter.html#executable-python-scripts


9

आप virtualenv का उपयोग करके इस समस्या को आज़मा सकते हैं

यहाँ test.py है

#! /usr/bin/env python
import sys
print(sys.version)

आभासी वातावरण बनाएँ

virtualenv test2.6 -p /usr/bin/python2.6
virtualenv test2.7 -p /usr/bin/python2.7

प्रत्येक वातावरण को सक्रिय करें फिर अंतरों की जाँच करें

echo $PATH
./test.py

9

यह सिर्फ यह निर्दिष्ट करता है कि आप किस दुभाषिया का उपयोग करना चाहते हैं। इसे समझने के लिए, टर्मिनल के माध्यम से एक फ़ाइल बनाएँ touch test.py, फिर उस फ़ाइल में टाइप करें:

#!/usr/bin/env python3
print "test"

और chmod +x test.pyअपनी स्क्रिप्ट को निष्पादन योग्य बनाने के लिए करें। इसके बाद जब आप कहते हैं कि ./test.pyआपको एक त्रुटि मिलनी चाहिए:

  File "./test.py", line 2
    print "test"
               ^
SyntaxError: Missing parentheses in call to 'print'

क्योंकि python3 प्रिंट ऑपरेटर को दबा नहीं पाता है।

अब आगे बढ़ें और अपने कोड की पहली लाइन को इसमें बदलें:

#!/usr/bin/env python2

और यह काम करेगा, मुद्रण testको stdout में, क्योंकि python2 प्रिंट ऑपरेटर का समर्थन करता है। तो, अब आप स्क्रिप्ट दुभाषियों के बीच स्विच करना सीख गए हैं।


9

यह मुझे लगता है कि फ़ाइलों को उस लाइन के बिना ही चलाते हैं।

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

हालांकि 2011 में, एक "पायथन लॉन्चर" विकसित किया गया था जो (कुछ हद तक) विंडोज के लिए इस लिनक्स व्यवहार की नकल करता है। यह सिर्फ़ यह चुनने के लिए सीमित है कि पायथन इंटरप्रेटर कौन-सा है - उदाहरण के लिए एक सिस्टम पर पायथन 2 और पायथन 3 के बीच चयन करने के लिए जहाँ दोनों स्थापित हैं। लांचर को वैकल्पिक रूप py.exeसे पायथन इंस्टॉलेशन के रूप में स्थापित किया गया है, और इसे .pyफाइलों के साथ जोड़ा जा सकता है ताकि लांचर उस रेखा की जांच करेगा और बदले में निर्दिष्ट पायथन इंटरप्रेटर संस्करण को लॉन्च करेगा।


6
वह भी इस्तेमाल हो सकता है $ python myscript.py
सिनान Marnür

मैंने लाइन नहीं होने से गलती की और अजगर स्क्रिप्टफ्रेम का उपयोग किया, और एक दिन मैंने बस किया ।/mcriptcript.py और सब कुछ काम करना बंद कर दिया, फिर सिस्टम को एहसास हुआ कि फाइल को स्क्रिप्ट के बजाय शेल स्क्रिप्ट के रूप में देखा जा रहा है।
गुआगुआ

8

इसका अर्थ "वास्तविक" उत्तर की तुलना में अधिक ऐतिहासिक जानकारी से है।

याद रखें कि दिन में आपके पास ऑपरेटिंग सिस्टम जैसे यूनिक्स के बहुत सारे थे, जिनके डिज़ाइनरों में सामान रखने की अपनी-अपनी धारणा थी, और कभी-कभी पायथन, पर्ल, बैश या बहुत सारे अन्य जीएनयू / ओपन सोर्स सामान शामिल नहीं थे।

यह विभिन्न लिनक्स वितरणों के लिए भी सही था। लिनक्स पर - प्री-एफएचएस [१] -आप के पास / usr / bin / या / usr / लोकल / बिन / में अजगर हो सकता है। या यह स्थापित नहीं हो सकता है, इसलिए आपने अपना स्वयं का निर्माण किया और इसे ~ / बिन में डाल दिया

सोलारिस सबसे खराब था जिस पर मैंने काम किया, आंशिक रूप से बर्कले यूनिक्स से सिस्टम वी में संक्रमण के रूप में। आप / usr /, / usr / लोकल /, / usr / ucb, / opt / आदि में सामान के साथ हवा बना सकते थे। कुछ बहुत लंबे रास्तों के लिए। मेरे पास Sunfreeware.com से सामान की यादें हैं, यह प्रत्येक पैकेज को अपनी निर्देशिका में स्थापित कर रहा है, लेकिन मुझे याद नहीं आ रहा है कि यह बायनेरिज़ को / usr / bin में सिम्प्लाइज़ करता है या नहीं।

ओह, और कभी-कभी / usr / bin एक NFS सर्वर [2] पर था।

तो envइस के आसपास काम करने के लिए उपयोगिता विकसित की गई थी।

तब आप लिख सकते थे #!/bin/env interpreterऔर जब तक रास्ता उचित था, चीजों को चलाने का एक उचित मौका था । बेशक, उचित मतलब (पायथन और पर्ल के लिए) जो आपने उचित पर्यावरण चर भी निर्धारित किया था। बैश / ksh / zsh के लिए यह सिर्फ काम किया।

यह महत्वपूर्ण था क्योंकि लोग शेल स्क्रिप्ट्स (जैसे पर्ल और पाइथन) के आसपास से गुजर रहे थे और अगर आप अपने Red Hat Linux वर्कस्टेशन पर हार्ड कोडेड / usr / bin / python करते हैं तो यह SGI पर खराब ब्रेक लगाने वाला था ... अच्छा, नहीं , मुझे लगता है कि IRIX ने सही जगह पर अजगर को रखा। लेकिन एक स्पार्क स्टेशन पर यह बिल्कुल नहीं चल सकता है।

मुझे अपने स्पार्क स्टेशन की याद आती है। लेकिन ढेर सारा नहीं। ठीक है, अब आप मुझे ई-बे पर ट्रोल कर रहे हैं। Bastages।

[१] फ़ाइल-सिस्टम पदानुक्रम मानक। https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard

[२] हाँ, और कभी-कभी लोग सामान की तरह करते हैं। और नहीं, मैंने अपनी बेल्ट पर या तो शलजम या प्याज नहीं पहना था।


5

यदि आप अपनी स्क्रिप्ट को वर्चुअल वातावरण में चला रहे हैं venv, तो कहें , तब which pythonकाम करते समय निष्पादित venvकरना पायथन इंटरप्रेटर का मार्ग प्रदर्शित करेगा:

~/Envs/venv/bin/python

ध्यान दें कि आभासी वातावरण का नाम पाइथन इंटरप्रेटर के मार्ग में सन्निहित है। इसलिए, अपनी स्क्रिप्ट में इस पथ को हार्डकोड करने से दो समस्याएं होंगी:

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

इसलिए, जोनाथन के जवाब में जोड़ने के लिए , आदर्श शेबंग है #!/usr/bin/env python, न केवल OSes में पोर्टेबिलिटी के लिए, बल्कि आभासी वातावरण में पोर्टेबिलिटी के लिए भी!


3

के बीच पोर्टेबिलिटी मुद्दों को ध्यान में रखते python2और python3, आप हमेशा जब तक कि आपके कार्यक्रम दोनों के साथ संगत है या तो संस्करण निर्दिष्ट करना चाहिए।

कुछ वितरण अभी कुछ समय के लिए pythonसहमे python3हुए हैं - pythonहोने का भरोसा न करें python2

यह पीईपी 394 द्वारा जोर दिया गया है :

प्लेटफार्मों के बीच मतभेदों को सहन करने के लिए, पायथन इंटरप्रेटर को लागू करने की आवश्यकता वाले सभी नए कोड को अजगर को निर्दिष्ट नहीं करना चाहिए, बल्कि या तो python2 या python3 (या अधिक विशिष्ट python2.x और python3.x संस्करणों को निर्दिष्ट करना चाहिए; माइग्रेशन नोट्स देखें ) । यह भेद शेलबैंग में किया जाना चाहिए, जब शेल स्क्रिप्ट से आह्वान किया जाता है, जब सिस्टम के माध्यम से आह्वान किया जाता है () कॉल, या किसी अन्य संदर्भ में आह्वान करते समय।


2

यह दुभाषिया को बताता है कि अजगर के किस संस्करण के साथ कार्यक्रम चलाने के लिए जब आपके पास अजगर के कई संस्करण हैं।


0

यह आपको निष्पादन योग्य का चयन करने की अनुमति देता है जिसे आप उपयोग करना चाहते हैं; जो कि बहुत आसान है अगर शायद आपके पास कई अजगर स्थापित हैं, और प्रत्येक में अलग-अलग मॉड्यूल हैं और चुनना चाहते हैं। जैसे

#!/bin/sh
#
# Choose the python we need. Explanation:
# a) '''\' translates to \ in shell, and starts a python multi-line string
# b) "" strings are treated as string concat by python, shell ignores them
# c) "true" command ignores its arguments
# c) exit before the ending ''' so the shell reads no further
# d) reset set docstrings to ignore the multiline comment code
#
"true" '''\'
PREFERRED_PYTHON=/Library/Frameworks/Python.framework/Versions/2.7/bin/python
ALTERNATIVE_PYTHON=/Library/Frameworks/Python.framework/Versions/3.6/bin/python3
FALLBACK_PYTHON=python3

if [ -x $PREFERRED_PYTHON ]; then
    echo Using preferred python $ALTERNATIVE_PYTHON
    exec $PREFERRED_PYTHON "$0" "$@"
elif [ -x $ALTERNATIVE_PYTHON ]; then
    echo Using alternative python $ALTERNATIVE_PYTHON
    exec $ALTERNATIVE_PYTHON "$0" "$@"
else
    echo Using fallback python $FALLBACK_PYTHON
    exec python3 "$0" "$@"
fi
exit 127
'''

__doc__ = """What this file does"""
print(__doc__)
import platform
print(platform.python_version())

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