स्क्रिप्ट चलाने के लिए ./ और sh के बीच क्या अंतर है?


71

मैंने एक साधारण स्क्रिप्ट लिखी है। जब मैं दौड़ता हूं sh <myscriptname.sh>, मुझे सही आउटपुट मिला है, लेकिन जब मैं दौड़ता ./<myscriptname.sh>हूं, तो मुझे एक त्रुटि मिली है।

जब मैं करता हूं shऔर क्या अंतर होता है ./?


15
केवल यह कहने के बजाय, "मुझे एक त्रुटि मिलती है", यह मदद करता है कि यदि आपने जो त्रुटि कहा है, उसमें आपको चिपकाया जाएगा।
२३:३५

जवाबों:


67

जब आप स्क्रिप्ट इंटरप्रेटर प्रोग्राम में फ़ाइलनाम पास करके किसी स्क्रिप्ट को चलाते हैं, तो आप स्क्रिप्ट के साथ इंटरप्रिटर प्रोग्राम चला रहे होते हैं क्योंकि उसमें एक तर्क दिया जाता है। उदाहरण के लिए, यह 'फ़ाइलनाम.श' तर्क के साथ प्रक्रिया 'श' की तरह दिखेगा। shदुभाषिया फ़ाइल खोल रहा है।

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

आपको यह सुनिश्चित करना चाहिए कि आपके पास एक धमाकेदार रेखा हो:

#!/bin/bash
# bash script here

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

एक बार आपके पास अपनी स्क्रिप्ट होने के बाद, सुनिश्चित करें कि आपने निष्पादन अनुमतियाँ सेट की हैं:

chmod a+x filename.sh

तब आप स्क्रिप्ट को अपनी प्रक्रिया के रूप में चला सकते हैं:

./filename.sh

या फ़ाइल को एक अच्छे प्रोग्राम के नाम से एक ज्ञात स्थान में रखें, जैसे /usr/sbinऔर कहीं से भी चलाएं:

sudo cp filename.sh /usr/sbin/program-name
program-name

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

यह पहचान के लिए भी अच्छा है। यदि आप topप्रोग्राम में जाते हैं, तो बैंग लाइन के बिना चलने वाली स्क्रिप्ट में सिर्फ दुभाषिया का नाम होगा bash, perlया python। लेकिन अगर कोई स्क्रिप्ट सही अनुमतियों के साथ चलाया जाता है, तो स्क्रिप्ट का नाम दिखाता है।

नोट: यदि आप ऐसी स्क्रिप्ट वितरित करना चाहते हैं जो सभी के लिए सुलभ हो, तो कृपया इसे स्थापित करने के लिए एक मैन पेज और एक डिबेट पैकेज बनाएं। हमें ऑनलाइन यादृच्छिक स्क्रिप्ट की संख्या को कम करने और उन डेब्स की संख्या को बढ़ाने की आवश्यकता है जिन्हें अनइंस्टॉल किया जा सकता है।


1
आप एक निजी बिन फ़ोल्डर का भी उपयोग कर सकते हैं: अपने घर के फ़ोल्डर में एक बिन फ़ोल्डर बनाएं लॉग आउट करें और पीछे लॉग इन करें और फिर आपको उस फ़ोल्डर में किसी भी स्क्रिप्ट को बिना या
पापुकायजा

बेशक, लेकिन अपने घर के फ़ोल्डर को अपने PATH में जोड़ने से थोड़ा सिरदर्द हो सकता है। बेहतर चीजें स्थापित करें। हालाँकि स्थानीय उपयोगकर्ता संकुल की स्थापना की अनुमति देने के लिए डिफ़ॉल्ट रूप से पथ में ~ / .local / बिन को जोड़ने की कुछ चर्चा थी।
मार्टिन ओवेन्स -डोक्टोर्मो-

ध्यान दें कि डिफ़ॉल्ट दुभाषिया है bash, नहीं sh
नाथन उस्मान

1
स्क्रिप्ट पर एक्सटेंशन न डालें, खासकर तब जब आप इसे डालते हैं PATH
जिरह

1
/usr/local/binशायद तब बेहतर होता है /usr/sbin- यह इंगित करता है कि यह कार्यक्रम वितरण का हिस्सा होने के बजाय इस मशीन के लिए स्थानीय है।
ग्लेन जैकमैन 20

41

लघु संस्करण:

  • shकमांड-लाइन दुभाषिया (डैश) है।
    रनिंग sh my_scriptडैश को स्क्रिप्ट की व्याख्या करता है।

  • ./पहली पंक्ति को देखकर पता लगाने की कोशिश करता है कि किस दुभाषिया का उपयोग करना है। जैसे #!/bin/bash, या यहां तक ​​कि #!/bin/ruby(चलने के विपरीत ruby my_script)।


7
यह वास्तव में नहीं है ./जो कुछ भी पाता है, यह सिस्टम निष्पादन विधि है जो फ़ाइल के पहले दो बाइट्स को देखता है।
मार्टिन ओवेन्स -डोक्टोर्मो-

9
पूर्ण रूप से। यहाँ यह सब बहुत लंबी व्याख्या है। मैं जा रहा हूँ व्यावहारिक :)
Stefano Palazzo

जब आप उपयोग करते हैं shऔर फ़ाइल में एक श-बैंग होता है, तो क्या इसका अर्थ है कि श-बैंग को अनदेखा किया जाएगा या क्या यह शेल को खोलेगा जहां shलिंक भी हैं और फिर शायद कुछ अन्य शेल या यह क्या करता है :)?
आरं

5

फर्क तुम करते हो,

  • के साथ sh, आप एक प्रोग्राम चला रहे हैं जो आपकी स्क्रिप्ट में उन पंक्तियों की व्याख्या करेगा जैसे आपने उन्हें टर्मिनल के इंटरैक्टिव प्रॉम्प्ट पर टाइप किया होगा,

  • साथ ./आप एक शॉर्टकट यह सोचते हैं कि स्क्रिप्ट मौजूदा निर्देशिका में सिर्फ यहीं है आप में बैठे हैं और यह निष्पादन योग्य रहेगा (क्योंकि उदाहरण के लिए आप जारी कर रहे हैं chmod +x myscript.sh), तो आप भविष्य समय के लिए अमूल्य समय की बचत :-)


3
+1 केवल यह बताने के लिए कि फ़ाइल निष्पादन योग्य होनी चाहिए।
मिकेल

2
ध्यान दें कि shफ़ाइल के साथ जरूरी निष्पादन योग्य नहीं होना चाहिए।
आरं

3

तीन मुख्य कारण हैं जिनसे आपको त्रुटि हो सकती है:

  • फ़ाइल को ठीक करने के लिए निष्पादन योग्य
    रन नहीं chmod +x <myscriptname.sh>है
  • विभाजन स्क्रिप्ट चलाने की अनुमति नहीं देता ("आरोहित है noexec")
    स्क्रिप्ट को कॉपी करें/usr/local/bin
  • #!लाइन में त्रुटि है
    यकीन है कि पहली पंक्ति है बनाना #!/bin/shया#!/bin/bash

यदि आपकी पहली पंक्ति सही दिखती है, लेकिन फिर भी काम नहीं कर रहा है, तो सुनिश्चित करें कि फ़ाइल में DOS लाइन अंत नहीं है।

त्रुटि कुछ इस तरह दिखाई देगी:

$ ./myscript.sh
bash: ./myscript.sh: /bin/bash^M: bad interpreter: No such file or directory

आप इसे चलाकर ठीक कर सकते हैं dos2unix <myscriptname.sh>, या यदि आपके पास ऐसा नहीं है, तो
perl -p -i -e 's/\r\n$/\n/' <myscriptname.sh>


0

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

इसलिए समाधान काफी सरल है। देखो कि श कमांड (ls -al / bin / sh) के पीछे क्या है, और पहली पंक्ति के रूप में #! / Bin / जो कुछ भी है (या यदि आपकी स्क्रिप्ट में ऐसा कुछ है तो इसे संपादित करें) # / / बिन / जो कुछ भी है।

और वैकल्पिक रूप से स्क्रिप्ट में कुछ बग हो सकते हैं। निर्भरता की तरह, जो श से मिलती है, लेकिन दुभाषिया नहीं है जो वास्तव में उपयोग किया जाता है।


0
mkdir ~/bin ; cp myscript.sh ~/bin/

echo "export PATH="$PATH:/home/$USER/bin" >> ~/.profile ; source ~/.profile ; 

नहीं /usr/sbin, यह गैर-आवश्यक प्रशासनिक साधनों के लिए है, /usr/local/binयदि आप नहीं चाहते हैं तो बेहतर विकल्प है ~/bin/, लेकिन sudoजितना संभव हो उतना बचने की सलाह दी जाती है।


उबंटू पर, डिफ़ॉल्ट में ~/.profileपहले से ही जोड़ने के लिए कोड है ~/bin, अगर यह मौजूद है, तो PATH। किसी अन्य नोट पर, स्क्रिप्ट पर एक्सटेंशन न डालें।
जिरह

1
मैं <myscriptname.sh> का उल्लेख कर रहा था, लेकिन स्क्रिप्ट पर एक्सटेंशन न लगाने का औचित्य क्या है? मैं आम तौर पर ऐसा करता हूं क्योंकि सादे पाठ की फाइलें दिखाई देती हैं, जो मुझे बायनेरिज़ को संपादित करने की कोशिश में रहती हैं जो मैं ~ / बिन / में भी रखता हूं। ( ls ~/bin/|wc -l = 428) मैंने वहाँ बहुत सारा सामान रखा है;)
जोये १

कल्पना कीजिए कि आप एक विशिष्ट कार्य को प्राप्त करने के लिए एक स्क्रिप्ट लिखते हैं। फिर आप महसूस करते हैं कि इस विशेष स्क्रिप्ट को अजगर में लिखना इसे और अधिक कुशल बना देगा, इसलिए आप इसे अजगर में फिर से लिखते हैं। अब आपके पास दो विकल्प हैं। 1) अब बहुत भ्रामक .sh- एक्सटेंशन, या 2 छोड़ दें) स्क्रिप्ट का नाम बदलें और नए नाम का उपयोग करने के लिए स्क्रिप्ट के सभी उपयोगों को खोजें और बदलें। यदि आप स्क्रिप्ट देखते हैं /binऔर /usr/binआप देखेंगे कि वे एक्सटेंशन का उपयोग नहीं करते हैं।
जिरह
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.