python - उनक - भाषा और लिपि की सूची




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

ऐसा लगता है कि फाइलें उस लाइन के बिना समान चलती हैं।

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

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

ऐसा लगता है कि फाइलें उस लाइन के बिना समान चलती हैं।


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

$ /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 में मौजूद नहीं है।

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

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

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

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

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

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

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

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

एनवी यूटिलिटी आपको पथ पर कमांड का आह्वान करने की अनुमति देती है:

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


एक और अधिक, अपूर्ण, लेकिन अभी भी उपयोगी प्रतिक्रिया: आभासी पर्यावरण संगतता। Google वर्चुअलएनवी। उत्पादन कोड के लिए इसका इस्तेमाल करें।


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

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

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


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

2.2.2। निष्पादन योग्य पायथन लिपियों

बीएसडी'श यूनिक्स सिस्टम पर, पाइथन स्क्रिप्ट को सीधे लाइन निष्पादित करने के साथ, खोल स्क्रिप्ट जैसे निष्पादन योग्य बनाया जा सकता है

#! /usr/bin/env python3.2

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


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

~/Envs/venv/bin/python

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

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

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


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

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

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


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

#!/usr/bin/env python

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


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


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

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

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

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

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

अब आगे बढ़ें और अपने कोड की पहली पंक्ति को यहां बदलें:

#!/usr/bin/env python2

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


यह स्क्रिप्ट बताता है कि पाइथन निर्देशिका कहां है!

#! /usr/bin/env python

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

कुछ वितरण कुछ समय के लिए python3 के साथ python3 किए गए python को शिपिंग कर रहे हैं - python पर python पर भरोसा न करें।

पीईपी 3 9 4 पर यह जोर दिया जाता है:

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


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

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

./something

लिनक्स पर, यह exec सिस्टम कॉल को किसी पूर्ण पथ के साथ कॉल करता something

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

अगर ((बीआरपीएम-> बफ [0]! = '#') || (बीआरपीएम-> बफ [1]! = '!'))

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

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

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

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

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

#!/a

और एक निष्पादन योग्य फ़ाइल /a

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

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

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

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





shebang