मैंने एक साधारण स्क्रिप्ट लिखी है। जब मैं दौड़ता हूं sh <myscriptname.sh>
, मुझे सही आउटपुट मिला है, लेकिन जब मैं दौड़ता ./<myscriptname.sh>
हूं, तो मुझे एक त्रुटि मिली है।
जब मैं करता हूं sh
और क्या अंतर होता है ./
?
मैंने एक साधारण स्क्रिप्ट लिखी है। जब मैं दौड़ता हूं sh <myscriptname.sh>
, मुझे सही आउटपुट मिला है, लेकिन जब मैं दौड़ता ./<myscriptname.sh>
हूं, तो मुझे एक त्रुटि मिली है।
जब मैं करता हूं sh
और क्या अंतर होता है ./
?
जवाबों:
जब आप स्क्रिप्ट इंटरप्रेटर प्रोग्राम में फ़ाइलनाम पास करके किसी स्क्रिप्ट को चलाते हैं, तो आप स्क्रिप्ट के साथ इंटरप्रिटर प्रोग्राम चला रहे होते हैं क्योंकि उसमें एक तर्क दिया जाता है। उदाहरण के लिए, यह 'फ़ाइलनाम.श' तर्क के साथ प्रक्रिया 'श' की तरह दिखेगा। 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
। लेकिन अगर कोई स्क्रिप्ट सही अनुमतियों के साथ चलाया जाता है, तो स्क्रिप्ट का नाम दिखाता है।
नोट: यदि आप ऐसी स्क्रिप्ट वितरित करना चाहते हैं जो सभी के लिए सुलभ हो, तो कृपया इसे स्थापित करने के लिए एक मैन पेज और एक डिबेट पैकेज बनाएं। हमें ऑनलाइन यादृच्छिक स्क्रिप्ट की संख्या को कम करने और उन डेब्स की संख्या को बढ़ाने की आवश्यकता है जिन्हें अनइंस्टॉल किया जा सकता है।
bash
, नहीं sh
।
PATH
।
/usr/local/bin
शायद तब बेहतर होता है /usr/sbin
- यह इंगित करता है कि यह कार्यक्रम वितरण का हिस्सा होने के बजाय इस मशीन के लिए स्थानीय है।
लघु संस्करण:
sh
कमांड-लाइन दुभाषिया (डैश) है।
रनिंग sh my_script
डैश को स्क्रिप्ट की व्याख्या करता है।
./
पहली पंक्ति को देखकर पता लगाने की कोशिश करता है कि किस दुभाषिया का उपयोग करना है। जैसे #!/bin/bash
, या यहां तक कि #!/bin/ruby
(चलने के विपरीत ruby my_script
)।
./
जो कुछ भी पाता है, यह सिस्टम निष्पादन विधि है जो फ़ाइल के पहले दो बाइट्स को देखता है।
sh
और फ़ाइल में एक श-बैंग होता है, तो क्या इसका अर्थ है कि श-बैंग को अनदेखा किया जाएगा या क्या यह शेल को खोलेगा जहां sh
लिंक भी हैं और फिर शायद कुछ अन्य शेल या यह क्या करता है :)?
फर्क तुम करते हो,
के साथ sh
, आप एक प्रोग्राम चला रहे हैं जो आपकी स्क्रिप्ट में उन पंक्तियों की व्याख्या करेगा जैसे आपने उन्हें टर्मिनल के इंटरैक्टिव प्रॉम्प्ट पर टाइप किया होगा,
साथ ./
आप एक शॉर्टकट यह सोचते हैं कि स्क्रिप्ट मौजूदा निर्देशिका में सिर्फ यहीं है आप में बैठे हैं और यह निष्पादन योग्य रहेगा (क्योंकि उदाहरण के लिए आप जारी कर रहे हैं chmod +x myscript.sh
), तो आप भविष्य समय के लिए अमूल्य समय की बचत :-)
sh
फ़ाइल के साथ जरूरी निष्पादन योग्य नहीं होना चाहिए।
तीन मुख्य कारण हैं जिनसे आपको त्रुटि हो सकती है:
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>
।
और जवाब है कि श बहुत लोकप्रिय शेल के लिए नाम है। लेकिन पुराने और दूसरों के द्वारा प्रतिस्थापित। आजकल श को मशीन पर स्थापित अन्य गोले से जोड़ा जाता है। उदाहरण के लिए मैंने वहां बैश डाला है। श से किसी भी शेल को चलाना आमतौर पर मूल 'शेल' व्यवहार के साथ कुछ 'कम्पैटिबिलिटी' मोड को ट्रिगर करता है।
इसलिए समाधान काफी सरल है। देखो कि श कमांड (ls -al / bin / sh) के पीछे क्या है, और पहली पंक्ति के रूप में #! / Bin / जो कुछ भी है (या यदि आपकी स्क्रिप्ट में ऐसा कुछ है तो इसे संपादित करें) # / / बिन / जो कुछ भी है।
और वैकल्पिक रूप से स्क्रिप्ट में कुछ बग हो सकते हैं। निर्भरता की तरह, जो श से मिलती है, लेकिन दुभाषिया नहीं है जो वास्तव में उपयोग किया जाता है।
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
। किसी अन्य नोट पर, स्क्रिप्ट पर एक्सटेंशन न डालें।
ls ~/bin/|wc -l = 428
) मैंने वहाँ बहुत सारा सामान रखा है;)
/bin
और /usr/bin
आप देखेंगे कि वे एक्सटेंशन का उपयोग नहीं करते हैं।