.sh निर्दिष्ट एक्सटेंशन?


12

ऐसा क्यों है कि कुछ सिस्टम .shफ़ाइल के नाम को बिना एक्सटेंशन के निर्दिष्ट करके फ़ाइल चलाएंगे और अन्य को नाम प्लस एक्सटेंशन की आवश्यकता है? मेरे मामले में मैं इन निर्देशों का पालन ​​करते हुए आदेशों की एक श्रृंखला लिखने की कोशिश कर रहा हूं ।

मैं अब एक्सटेंशन निर्दिष्ट कर रहा हूं, लेकिन बिना कमांड चलाने में सक्षम .shहोना बेहतर होगा।


4
.shविस्तार के रूप में उपयोग करना कई परिस्थितियों में बुरा अभ्यास माना जाता है: यह विपरीत है कि अन्य आदेशों का नाम कैसे रखा जाता है (आप नहीं चलाते हैं ls.elf), यह अक्सर भ्रामक foo.shहोता है (यदि आपकी शुरुआत होती है #!/bin/bash, तो sh foo.shइसे चलाने के लिए इसे बनाने की तुलना में एक अलग दुभाषिया के साथ चलेगा। ), और यदि आप foo.shएक पायथन प्रोग्राम होने के लिए फिर से लिखते हैं, तो उस एक्सटेंशन का उपयोग करने का मतलब है कि आपको अब-भ्रामक नाम रखने और उसे कॉल करने वाले प्रत्येक प्रोग्राम को फिर से लिखने के बीच चुनने की आवश्यकता है।
चार्ल्स डफी

2
... जहां यह है , एक सबसे अच्छा अभ्यास खोल पुस्तकालयों है के साथ नहीं आदेश +xसेट - जहां foo.shएक पुस्तकालय है कि किसी भी POSIX खोल में sourced किया जा सकता है, foo.bashपार्टी में sourced किया जा सकता है, foo.kshksh, आदि में
चार्ल्स डफी

जवाबों:


39

तुम उलझन में हो। .shविस्तार केवल मनुष्य के लिए एक संकेत है, और पूरी तरह से नहीं पर कैसे सिस्टम फ़ाइल हैंडल प्रभाव पड़ता है। यूनिक्स / लिनक्स ने विंडोज की Secrets.pdf.exeगड़बड़ी नहीं की।

जब आप टाइप करते हैं तो यह होता है foo:

  1. के लिए पुनर्निर्देशन STDIN, STDOUTऔर STDERRस्थापित किए जाते हैं।

  2. शेल इसकी आंतरिक हैश तालिका की जांच करता है कि क्या यह पहले से ही एक $PATHप्रविष्टि के लिए जानता है foo। यदि कोई भी मौजूद नहीं है, तो शेल निर्देशिकाओं को खोजता है $PATH, एक फ़ाइल की तलाश में है जिसे fooएक्सट्यूट बिट सेट किया गया है यह फ़ाइल अनुमतियों में है। पहली fooजीत।

  3. यदि फ़ाइल के पहले दो बाइट्स fooहैं #!, तो अगले स्ट्रिंग को चलाने के लिए दुभाषिया का नाम है। इस प्रकार #!/bin/bashएक बैश स्क्रिप्ट का #!/usr/bin/perlपरिचय , एक पर्ल स्क्रिप्ट का परिचय, आदि।

  4. यदि फ़ाइल के साथ शुरू होता है \177ELF, तो यह एक द्विआधारी निष्पादन योग्य है, और ld.soइसे शुरू करता है।

अधिक विस्तृत विवरण के लिए पढ़ें man execveऔर पढ़ें man ld.so


15
हाँ, लिनक्स पर आप उस नाम से कोई सुराग नहीं लेकर उस
रहस्य से मुक्त रह सकते हैं

1
@OrangeDog मुझे पता है कि आप मजाक कर रहे हैं, लेकिन मुझे ऐसा लगता है कि मुझे यह बताना होगा कि निष्पादन योग्य बिट ( chmod +x) बहुत ज्यादा हल करता है, है ना?
wchargin

3
@Chargin जो निर्भर करता है कि आपका फाइल सिस्टम कितना अच्छा व्यवहार करता है (उदाहरण के लिए एक माउंटेड नेटवर्क शेयर या NTFS विभाजन संभवतः xहर चीज पर बिट सेट कर सकता है ) और जहां से फाइल आई (निर्देशिका के नियंत्रण के साथ किसी भी प्रक्रिया को अनुमतियों को सेट करने में धोखा दिया जा सकता है) । तो, यह इसे कम कर देता है, लेकिन मैं यह नहीं कहूंगा कि यह इसे हल करता है।
IMSoP

2
@Chargin, अभी तक, लेकिन मुझे लगता है कि उनकी बात यह है कि आमतौर पर फ़ाइल प्रबंधक निष्पादन योग्य बिट नहीं दिखाते हैं, अर्थात एक एक्सटेंशन की तरह "मनुष्यों के लिए संकेत" नहीं है।
पॉल ड्रेपर

1
मैं गलती से कभी नहीं क्लिक करता Secrets.pdf.exeहूं क्योंकि मैं हमेशा बेवकूफ hide file extensionसुविधा को निष्क्रिय करता हूं
phuclv

12

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

किसी फ़ाइल के लिए दी गई निष्पादन योग्य अनुमति क्या मायने रखती है। जिसे आप चेक कर सकते हैं

ls -l /path/to/file

निष्पादन योग्य चल रहे हैं

स्क्रिप्ट चलाने के लिए आम तौर पर कई तरीके होते हैं।

  • यदि आपकी वर्तमान निर्देशिका स्क्रिप्ट के समान है, और स्क्रिप्ट के पास निष्पादन योग्य अनुमतियाँ हैं, तो आप इसे इस तरह से चला सकते हैं ./my_script_name.वर्तमान निर्देशिका का मतलब है।
  • यदि आपकी वर्तमान निर्देशिका अलग है और स्क्रिप्ट में निष्पादन योग्य अनुमतियाँ हैं, तो आप इसे पूर्ण पथ निर्दिष्ट करके चला सकते हैं: /home/user/bin/my_script_name

(उपर्युक्त दो विधियाँ निष्पादन योग्य अनुमति सेट पर निर्भर करती हैं; चाहे फ़ाइल $PATHचर का हिस्सा हो या न हो , अप्रासंगिक है। #!लाइन की उपस्थिति भी मायने रखती है, इसके बिना, यह स्क्रिप्ट आपके द्वारा खोले गए वर्तमान शेल द्वारा निष्पादित की जाएगी। यदि मेरे पास cshस्क्रिप्ट है। उस लाइन के बिना, और इसे साथ में चलाने की कोशिश करें ./my_script.csh, यह विफल हो जाएगा)

  • यदि आपकी स्क्रिप्ट निर्देशिका में स्थित है जो आपके $PATHचर का हिस्सा है , तो आप इसे केवल नाम से बुला सकते हैं। आप chmodकमांड लाइन में कमांड को केवल उसका नाम लिखकर कॉल कर सकते हैं क्योंकि यह /binफ़ोल्डर में है। /binहमेशा $PATHचर का हिस्सा है । इस मामले में निष्पादन योग्य अनुमतियाँ और स्क्रिप्ट मामले का स्थान
  • एक व्याख्याकार को कमांड और स्क्रिप्ट को तर्क के रूप में निर्दिष्ट करना। इस तरह स्क्रिप्ट दुभाषिया को इनपुट फ़ाइल के रूप में काम करेगी।
  • एक फ़ाइल सोर्सिंग। . filename.shया source filename.shस्क्रिप्ट का इलाज किया जा के रूप में अगर यह कीबोर्ड इनपुट, यानी था जैसे कि यह कमांड लाइन में सीधे टाइप किया गया था कर देगा। इस मामले में निष्पादन योग्य अनुमति और स्थान मायने नहीं रखते

उदाहरण

उदाहरण # 1, अनुमतियों को निष्पादित करने के लिए दुभाषिया के साथ चल रहा है

$-> ls -l abc.py                                                               
-rw-rw-r-- 1 xieerqi xieerqi 44 Apr 27 22:39 abc.py
$-> python abc.py                                                              
a
b
c

उदाहरण # 2, ./निष्पादन योग्य अनुमति सेट, शबंग लाइन सेट के साथ चल रहा है ।

$-> cat abc.py                                                                 
#!/usr/bin/env python
for letter in 'a' 'b' 'c' :
   print letter
$-> ls -l abc.py
-rwxrwxr-x 1 xieerqi xieerqi 66 Apr 27 23:02 abc.py*
$-> ./abc.py                                                                   
a
b
c

उदाहरण # 3, शेबंग लाइन सेट के बिना चल रहा है (विफल रहता है, क्योंकि बैश अजगर स्क्रिप्ट नहीं पढ़ सकता है; कोई भी शेब लाइन लाइन चालू शेल को दुभाषिया नहीं मानता है)

$-> cat abc.py                                                                 
for letter in 'a' 'b' 'c' :
   print letter
$-> ./abc.py                                                                   
./abc.py: 2: ./abc.py: Syntax error: word unexpected (expecting "do")

उदाहरण # 4, चल स्क्रिप्ट जिसमें निष्पादन योग्य अनुमतियाँ सेट फ़ोल्डर हैं जो $PATHचर का हिस्सा है

#  /home/xieerqi/bin is part of my path variable
$-> echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/opt/microchip/xc16/v1.25/bin:/opt/microchip/xc32/v1.40/bin:/opt/microchip/xc8/v1.35/bin:/home/xieerqi/bin:/home/xieerqi/bin/sh

$-> # current directory is /home/xieerqi
$-> pwd
/home/xieerqi
$-> # move the file to ~/bin
$-> mv ~/abc.py ~/bin/abc.py
$-> # now I can run it just by calling the name
$-> abc.py
/home/xieerqi/bin/abc.py: 2: /home/xieerqi/bin/abc.py: Syntax error: word unexpected (expecting "do")
$-> # Syntax error because again, no interpreter specified.                    
$-> # must add #!/usr/bin/env python
$-> vi /home/xieerqi/bin/abc.py          
$-> # after adding the line with vi text editor, we can run
$-> abc.py                                                                     
a
b
c

उदाहरण # 5, एक्सटेंशन निकालना, अभी भी चलता है क्योंकि एक्सटेंशन कोई फर्क नहीं पड़ता, लेकिन इसकी अनुमति है और इसका हिस्सा है $PATH:

$-> mv ~/bin/abc.py  ~/bin/abc                                                 
$-> abc
a
b
c

मैंने कमांड चलाई और मुझे यह '-rwxr-x ---' मिला। मुझे पढ़ने के लिए क्या मूल्य चाहिए और मैं इसे कैसे बदल सकता हूं?
फिलिप किर्कब्राइड

या आप कह रहे हैं कि मुझे केवल 'filename.sh' का नाम बदलकर 'फ़ाइल नाम' रखना चाहिए?
फिलिप किर्कब्राइड

1
@PhilipKirkbride नाम अप्रासंगिक है। आप अपनी कमान कैसे चलाते हैं? कहाँ है ? क्या निर्देशिका यह आपके हिस्से में है PATH?
सर्गी कोलोडियाज़नी

@PhilipKirkbride मुझे स्पष्ट करने के लिए एक मिनट में अपने उत्तर का विस्तार करने दें।
सर्गी कोलोडियाज़नी

1
पर एक नजर डालें man chmodअनुमतियां सेट करने के लिए कैसे को देखने के लिए
निक Mertin

6

यहाँ पहले से ही अच्छी व्याख्या। मैं बस यह जोड़ना चाहता था कि आदर्श रूप से आपको निष्पादनयोग्य के लिए फ़ाइल एक्सटेंशन का उपयोग नहीं करना चाहिए।

आमतौर पर आपको अपेक्षाकृत कुछ आसान करने की आवश्यकता होती है और आप थोड़ा शेल स्क्रिप्ट के साथ शुरुआत करते हैं। समय के साथ आप अपनी स्क्रिप्ट में अधिक से अधिक कार्यक्षमता जोड़ना शुरू करते हैं, जब तक कि यह कुछ समय न आ जाए कि यह अप्राप्य हो जाता है या आपको कुछ कार्यक्षमता की आवश्यकता होती है जिसे आप आसानी से एक शेल स्क्रिप्ट के साथ पूरा नहीं कर सकते हैं और किसी अन्य भाषा में इस शेल स्क्रिप्ट को फिर से लिखने के बारे में सोचते हैं (अजगर) , पर्ल, ...?)।

स्क्रैच से पुनर्प्राप्त करना आमतौर पर एक त्रुटि माना जाता है, लेकिन स्क्रिप्ट के लिए यह समझ में आ सकता है क्योंकि आमतौर पर वे इतने बड़े नहीं होते हैं या बहुत अधिक कार्यक्षमता होती है। लेकिन मान लेते हैं कि किसी अन्य भाषा में स्क्रैच से फिर से लिखना संभव है, प्रारंभिक शेल स्क्रिप्ट की कार्यक्षमता और पैराम / झंडे को बनाए रखना।

इस स्क्रिप्ट के उपयोगकर्ताओं को इस भाषा परिवर्तन से अवगत होने की आवश्यकता नहीं है, वे एक ही कमांड को निष्पादित करते रहेंगे और यह काम करना जारी रखेगा।

यदि आपकी स्क्रिप्ट का नाम रखा गया था do-something.sh, तो यह जारी रह सकता है do-something.sh, लेकिन अब यह अजगर (उदाहरण के लिए) में लिखा गया है, और इसलिए आपका प्रारंभिक संकेत अब पूरी तरह से एक भ्रामक है।


4

बिना एक्सटेंशन के फाइलों को चलाने के लिए आपको नॉर्मल होने की जरूरत नहीं है, बस यह सुनिश्चित करें कि आपके पास (बैश स्क्रिप्ट के मामले में) बहुत ही पहली पंक्ति में उचित शेबंग लाइन है:

#!/bin/bash

तब आपको सिस्टम द्वारा फाइल को निष्पादन योग्य बनाने की आवश्यकता होती है

chmod 755 yourfilename

यह उसी तरह है जैसे chmod +x yourfilenameकि संख्याओं का उपयोग आसान समझाया जाता है।

यह जोड़ा गया अष्टक का एक नंबर ट्रिपल है, पहला नंबर उपयोगकर्ता के लिए खड़ा है, दूसरा समूह के लिए, और तीसरा दूसरों के लिए, इससे अधिक आप यहां पा सकते हैं ।

और अगर आप उसी निर्देशिका में हैं, जब आपकी स्क्रिप्ट ./इस तरह का उपयोग करना न भूलें :

./yourfilename

इसकी कोशिश की। मूल परिणामों से दुर्भाग्य से कोई अंतर नहीं है।
फिलिप किर्कब्राइड

@PhilipKirkbride ने मेरे संशोधित उत्तर पर एक नज़र डाली है, यह निश्चित रूप से कुछ और प्रकाश डालेगा।
विदेहोनथ

0

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

QDOS (क्विक एंड डर्टी ऑपरेटिंग सिस्टम, बाद में इसका नाम बदलकर IBM द्वारा "DOS" कर दिया गया, जब mirosoft ने इसे पायरेटेड कर दिया और अवैध रूप से इसे उन्हें बेच दिया) और विंडोज़ सहित CP / M के अन्य सस्ते रिप्पो, इस सब को मिक्स कर दिया क्योंकि उन सिस्टमों में ऐसा नहीं है फ़ाइलों पर अनुमतियों को निष्पादित करने जैसी चीज़। इसने पिछले 30-40 वर्षों में अनगिनत सुरक्षा f'ups लिए हैं। वास्तव में कुछ ही मिनट पहले मैं सिर्फ एक अजीब फँस ज़िप फ़ाइल के साथ कई जंक मेल MYPICTURE.JPG.zip करने के लिए नाम मिला :)

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