आपने इसे पिछड़ा हुआ पाया है। /bin/sh
इन दिनों लगभग एक बॉर्न शेल कभी नहीं होता है, और यह तब होता है जब आप एक #! /bin/sh
धमाके का उपयोग करते हैं तो आपको एक समस्या होती है ।
बोर्न शेल 70 के दशक के अंत में लिखा गया एक शेल था और पिछले थॉम्पसन शेल (जिसे भी कहा जाता है sh
) को प्रतिस्थापित किया गया था । 80 के दशक की शुरुआत में, डेविड कॉर्न ने बॉर्न शेल के लिए कुछ एक्सटेंशन लिखे, कुछ बग्स और डिज़ाइन के अजीबपन को ठीक किया (और कुछ को पेश किया) और इसे कॉर्न शेल कहा।
90 के दशक की शुरुआत में, POSIX ने कोर्न शेल के सबसेट के आधार पर sh
भाषा को निर्दिष्ट किया और Most 90 सिस्टम ने अब उन्हें /bin/sh
या तो कॉर्न शेल या शेल विनिर्देशन में बदल दिया है। बीएसडी के मामले में, उन्होंने धीरे-धीरे अपने को बदल दिया /bin/sh
, शुरू में (बाद में वे लाइसेंस के कारणों के लिए बॉर्न शेल का उपयोग नहीं कर सके) अल्मक्विस्ट शेल, बोर्न शेल का एक क्लोन जो कुछ ksh एक्सटेंशन के साथ था, इसलिए यह POSIX आज्ञाकारी बन गया।
आज, सभी POSIX प्रणालियों में एक शेल होता है sh
(सबसे अधिक बार, लेकिन जरूरी नहीं कि /bin
, POSIX उपयोगिताओं के पथ को निर्दिष्ट नहीं करता है) जो कि ज्यादातर POSIX अनुरूप है। यह आमतौर पर या तो ksh88, ksh93, pdksh, bash, ash या zsh² पर आधारित होता है, लेकिन बॉर्न शेल के रूप में नहीं, क्योंकि बॉर्न शेल कभी POSIX कंप्लेंट नहीं था। उन के गोले में से कुछ ( bash
, zsh
, yash
और कुछ pdksh
डेरिवेटिव एक POSIX शिकायत मोड जब के रूप में लागू करने के लिए सक्षम sh
और कर रहे हैं कम अन्यथा अनुरूप)।
bash
(कोर्न शेल का GNU उत्तर) वास्तव में एकमात्र खुला स्रोत शेल है (और एक ही कह सकता है कि वर्तमान में बनाए रखा जा सकता है क्योंकि अन्य आमतौर पर ksh88 पर आधारित होते हैं, जो 90 के दशक के बाद से कोई नई सुविधा नहीं मिली है) जिसे इस रूप में प्रमाणित किया गया है एक POSIX आज्ञाकारी होने के नाते sh
(macOS प्रमाणीकरण के भाग के रूप में)।
जब आप #! /bin/sh -
शी-बैंग के साथ एक स्क्रिप्ट लिखते हैं , तो आपको एक मानक sh
सिंटैक्स का उपयोग करना चाहिए (और उस स्क्रिप्ट में उपयोग की जाने वाली उपयोगिताओं के लिए भी मानक सिंटैक्स का उपयोग करना चाहिए यदि आप पोर्टेबल होना चाहते हैं, तो यह केवल शेल नहीं है जो शेल की व्याख्या करते समय शामिल है स्क्रिप्ट), तो यह कोई फर्क नहीं पड़ता कि उस मानक sh
वाक्यविन्यास दुभाषिया का क्या उपयोग किया जाता है ( ksh
, bash
...)।
इससे कोई फर्क नहीं पड़ता कि उन गोले के मानक पर एक्सटेंशन हैं जब तक आप उनका उपयोग नहीं करते हैं। यह सी कोड लिखने के लिए है, जब तक आप मानक सी कोड लिखते हैं और एक संकलक (जैसे gcc
) या दूसरे के एक्सटेंशन का उपयोग नहीं करते हैं , आपके कोड को संकलक कार्यान्वयन की परवाह किए बिना ठीक संकलित करना चाहिए बशर्ते कि संकलक आज्ञाकारी है।
इधर, अपने साथ #! /bin/sh
वह-बैंग, अपने मुख्य समस्या वाले सिस्टम होगा /bin/sh
बॉर्न शैल है कि उदाहरण की तरह मानक सुविधाओं का समर्थन नहीं करता के लिए $((1+1))
, $(cmd)
, ${var#pattern}
... में जो मामले आप की तरह काम arounds आवश्यकता हो सकती है:
#! /bin/sh -
if false ^ true; then
# in the Bourne shell, ^ is an alias for |, so false ^ true returns
# true in the Bourne shell and the Bourne shell only.
# Assume the system is Solaris 10 (older versions are no longer maintained)
# You would need to adapt if you need to support some other system
# where /bin/sh is the Bourne shell.
# We also need to fix $PATH as the other utilities in /bin are
# also ancient and not POSIX compatible.
PATH=`/usr/xpg6/bin/getconf PATH`${PATH:+:}$PATH || exit
export PATH
exec /usr/xpg4/bin/sh "$0" "$@"
# that should give us an environment that is mostly compliant
# to the Single UNIX Specification version 3 (POSIX.2004), the
# latest supported by Solaris 10.
fi
# rest of the script
वैसे, उबंटू डिफ़ॉल्ट रूप /bin/sh
से नहीं bash
है। यह dash
इन दिनों, एक शेल है जो नेटबीएसडी पर आधारित है sh
, खुद अल्मक्विस्ट शेल पर आधारित है जो ज्यादातर पॉसिक्स अनुपालन है इसके अलावा यह मल्टी-बाइट वर्णों का समर्थन नहीं करता है। Ubuntu और अन्य डेबियन-आधारित सिस्टम पर, आप के बीच चयन कर सकते हैं bash
और dash
के लिए /bin/sh
के साथ dpkg-reconfigure dash
) 4 । sh
डेबियन के साथ भेज दी गई लिपियों को दोनों गोले में समान काम करना चाहिए क्योंकि वे डेबियन नीति मानक (पोसिक्स मानक का एक सुपरसेट) में लिखे गए हैं। आप शायद वे भी मिल जाएगा में काम ठीक zsh
है sh
अनुकरण या bosh
(शायद नहीं ksh93
है और न ही yash
जो एक की जरूरत नहीं है local
builtin (Debian नीति नहीं बल्कि POSIX) द्वारा अपेक्षित)।
Unix.stackexchange.com पर दायरे की सभी प्रणालियों में sh
कहीं न कहीं एक POSIX है। उनमें से अधिकांश के पास एक है /bin/sh
(आप बहुत दुर्लभ मिल सकते हैं जिनके पास एक /bin
निर्देशिका नहीं है लेकिन आप शायद इस बारे में परवाह नहीं करते हैं), और यह आम तौर पर एक पॉसिक्स sh
दुभाषिया है (और दुर्लभ मामलों में (गैर-मानक) बॉर्न शेल के बजाय )।
लेकिन sh
एकमात्र शेल दुभाषिया निष्पादन योग्य है जिसे आप सिस्टम पर ढूंढना सुनिश्चित कर सकते हैं। अन्य गोले के लिए, आप सुनिश्चित कर सकते हैं कि macOS, Cygwin और अधिकांश GNU / Linux वितरण होंगे bash
। SYSV व्युत्पन्न OSes (Solaris, AIX ...) में आमतौर पर ksh88, संभवतः ksh93 होगा। OpenBSD, MirOS में pdksh व्युत्पन्न होगा। macOS होगा zsh
। लेकिन उसमें से, कोई गारंटी नहीं होगी। इस बात की कोई गारंटी नहीं है कि bash
या किसी अन्य गोले को /bin
या कहीं और स्थापित किया जाएगा (यह आमतौर /usr/local/bin
पर बीएसडी पर पाया जाता है जब उदाहरण के लिए स्थापित होता है)। और निश्चित रूप से स्थापित किए जाने वाले शेल के संस्करण की कोई गारंटी नहीं है।
ध्यान दें कि #! /path/to/executable
यह एक सम्मेलन नहीं है , यह सभी यूनिक्स की तरह गुठली ( डेनिस रिची द्वारा 80 के दशक की शुरुआत में शुरू की गई ) की एक विशेषता है जो एक पहली पंक्ति में दुभाषिया के मार्ग को निर्दिष्ट करके मनमानी फाइलों को निष्पादित करने की अनुमति देता है #!
। यह किसी भी निष्पादन योग्य हो सकता है।
जब आप ऐसी फ़ाइल निष्पादित करते हैं, जिसकी पहली पंक्ति शुरू होती है #! /some/file some-optional-arg
, तो कर्नेल निष्पादन के /some/file
साथ समाप्त होता है some-optional-arg
, स्क्रिप्ट का मार्ग और तर्क के रूप में मूल तर्क। आप देख सकते हैं कि पहली पंक्ति #! /bin/echo test
क्या हो रही है:
$ ./myscript foo
test ./myscript foo
जब आप /bin/sh -
इसके बजाय उपयोग करते हैं /bin/echo test
, तो कर्नेल निष्पादित होता है /bin/sh - ./myscript foo
, इसमें sh
संग्रहीत सामग्री कोड की व्याख्या करता है myscript
और उस पहली पंक्ति को अनदेखा करता है क्योंकि यह एक टिप्पणी है (शुरुआत के साथ #
)।
¹ संभवतः आज की एकमात्र प्रणाली जहाँ हममें से कोई भी एक /bin/sh
बॉर्न शेल पर आधारित है, वह सोलारिस है। सोलारिस उन कुछ यूनियनों में से एक है, जिन्होंने पिछड़ी अनुकूलता के लिए बॉर्न शेल रखने का फैसला किया है (पोसिक्स sh
भाषा पूरी तरह से नहीं है। बॉर्न शेल के साथ पीछे की ओर संगत) और (कम से कम डेस्कटॉप और पूर्ण सर्वर परिनियोजन के लिए) POSIX sh
कहीं और (में /usr/xpg4/bin/sh
, ksh88 पर आधारित) है, लेकिन सोलारिस 11 में बदल गया है जहां /bin/sh
अब ksh93 है। दूसरे लोग ज्यादातर दोषपूर्ण हैं।
² MacOS / एक्स हुआ करता था की , लेकिन बाद में करने के लिए बदल । यह POSIX कार्यान्वयन के रूप में इस्तेमाल किया जाने वाला प्राथमिक ध्यान नहीं है । इसका मोड मुख्य रूप से स्क्रिप्ट्स में POSIX कोड एम्बेड या कॉल करने में सक्षम है/bin/sh
zsh
bash
zsh
sh
sh
source
sh
zsh
³ हाल ही में, @schily ने POSIX आज्ञाकारी बनने के लिए ओपनसोलारिस शेल (एसवीआर 4 शेल पर आधारित, बॉर्न शेल के आधार पर) को बढ़ाया, कहा जाता है, bosh
लेकिन मुझे पता नहीं है कि यह अभी तक किसी भी सिस्टम पर उपयोग किया जाता है। इसके साथ ही ksh88
यह बॉर्न शेल के कोड के आधार पर एक दूसरा POSIX- अनुरूप शेल बनाता है
4 पुराने संस्करणों में, आप mksh
POSIX lksh
अवतार का उपयोग कर सकते हैं । यह मिर्क (पूर्व में MirBSD) शेल पर आधारित pdksh है, जो खुद फोर्सिथ शेल (बॉर्न शेल का एक और पुन: कार्यान्वयन) पर आधारित है)