अपेक्षाकृत हाल तक, आप हर जगह POSIX- संगत शेल होने पर भरोसा नहीं कर सकते ।
कई सिस्टम, विशेष रूप से पुराने, तकनीकी रूप से सिस्टम पर कहीं न कहीं एक POSIX- संगत शेल होते हैं , लेकिन यह जैसे अनुमानित स्थिति में नहीं हो सकता है /bin/sh
। यदि आप एक शेल स्क्रिप्ट लिख रहे हैं और इसे कई अलग-अलग प्रणालियों पर चलाना है, तो आप शेबंग लाइन कैसे लिखते हैं ? एक विकल्प आगे बढ़ने और उपयोग करने के लिए है /bin/sh
, लेकिन इस तरह की प्रणाली पर चलने के मामले में प्री-पॉसिक्स बॉर्न शेल बोली के लिए खुद को प्रतिबंधित करने का विकल्प चुनें।
प्री-पॉसिक बॉर्न गोले में बिल्ट-इन अंकगणित भी नहीं होता है; आप के लिए बाहर कॉल करनी होगी expr
या bc
कि किया जाना।
POSIX शेल के साथ भी, आप साहचर्य सरणियों और उन अन्य विशेषताओं को याद कर रहे हैं, जिन्हें हमने यूनिक्स स्क्रिप्टिंग भाषाओं में खोजने की उम्मीद की थी क्योंकि पर्ल पहली बार 1990 के दशक में लोकप्रिय हुए थे ।
इतिहास के इस तथ्य का अर्थ है कि आधुनिक बोर्न परिवार की शेल स्क्रिप्ट दुभाषियों में कई शक्तिशाली विशेषताओं को अनदेखा करने की दशकों पुरानी परंपरा है क्योंकि आप उन्हें हर जगह होने पर भरोसा नहीं कर सकते हैं।
यह अभी भी आज तक जारी है, वास्तव में: बैश को संस्करण 4 तक साहचर्य सरणियां नहीं मिलीं , लेकिन आपको आश्चर्य हो सकता है कि कितने सिस्टम अभी भी उपयोग में हैं, यह बैश 3 पर आधारित है। Apple अभी भी 2017 में macOS के साथ बैश 3 को जहाज करता है - जाहिरा तौर पर लाइसेंसिंग कारण - और यूनिक्स / लिनक्स सर्वर अक्सर बहुत लंबे समय के लिए उत्पादन में सभी लेकिन अछूते चलते हैं, इसलिए आपके पास एक स्थिर पुरानी प्रणाली अभी भी बैश 3 चल सकती है, जैसे कि सेंटोस 5 बॉक्स। यदि आपके पास इस तरह के सिस्टम आपके वातावरण में हैं, तो आप शेल स्क्रिप्ट्स में साहचर्य सरणियों का उपयोग नहीं कर सकते हैं जो उन पर चलना है।
यदि उस समस्या के लिए आपका उत्तर यह है कि आप केवल "आधुनिक" सिस्टम के लिए शेल स्क्रिप्ट लिखते हैं, तो आपको इस तथ्य से जूझना होगा कि अधिकांश यूनिक्स गोले के लिए अंतिम सामान्य संदर्भ बिंदु पोसिक्स शेल मानक है , जो काफी हद तक अपरिवर्तित था। 1989 में शुरू किया गया। उस मानक के आधार पर कई अलग-अलग गोले हैं, लेकिन वे सभी उस मानक से अलग-अलग डिग्री पर विचलन कर चुके हैं। साहचर्य सरणियों फिर से लेने के लिए, bash
, zsh
, और ksh93
सब है कि सुविधा है, लेकिन वहाँ कई कार्यान्वयन असंगतियां हैं। आपकी पसंद है, तो, करने के लिए है केवल बैश उपयोग करें, या केवल Zsh उपयोग करें, या केवल का उपयोग ksh93
।
यदि आपकी समस्या का उत्तर है, "तो बस बैश 4 स्थापित करें," या ksh93
, या जो भी हो, तो "पर्ल" या पायथन या रूबी को स्थापित करने के बजाय "बस" क्यों नहीं? यह कई मामलों में अस्वीकार्य है; चूक की बात।
बॉर्न परिवार शेल स्क्रिप्टिंग भाषाओं में से कोई भी मॉड्यूल का समर्थन नहीं करता है ।
निकटतम आप एक शेल स्क्रिप्ट में एक मॉड्यूल सिस्टम में आ सकते हैं .
- कमांड है - source
अधिक आधुनिक बॉर्न शेल वेरिएंट में उर्फ - जो एक उचित मॉड्यूल सिस्टम के सापेक्ष कई स्तरों पर विफल रहता है, जिनमें से सबसे बुनियादी नाम स्थान है ।
प्रोग्रामिंग भाषा के बावजूद, मानव समझ तब शुरू होती है जब किसी बड़े समग्र कार्यक्रम में कोई भी फ़ाइल कुछ हज़ार लाइनों से अधिक होती है। बहुत से कार्यक्रमों को हम कई फाइलों में विभाजित करते हैं, ताकि हम उनकी सामग्री को एक वाक्य या दो पर अधिक से अधिक सार कर सकें। फ़ाइल A कमांड लाइन पार्सर है, फ़ाइल B नेटवर्क I / O पंप है, फ़ाइल C लाइब्रेरी Z और बाकी प्रोग्राम के बीच का शिम है, आदि जब आपकी एकल फाइल को एक ही प्रोग्राम में असेंबल करने का एकमात्र तरीका पाठ्य समावेश है। , आप इस बात की एक सीमा रख सकते हैं कि आपके कार्यक्रम कितने बड़े हो सकते हैं।
तुलना के लिए, यह ऐसा होगा जैसे कि सी प्रोग्रामिंग भाषा में कोई लिंकर नहीं था, केवल #include
बयान। इस तरह की सी-लाइट बोली को कीवर्ड की आवश्यकता नहीं होगी जैसे कि extern
या static
। उन विशेषताओं में विद्यमानता की अनुमति होती है।
POSIX एकल शेल स्क्रिप्ट फ़ंक्शन के लिए चर को स्कोप करने के तरीके को परिभाषित नहीं करता है , एक फ़ाइल के लिए बहुत कम।
यह प्रभावी रूप से सभी चर को वैश्विक बनाता है , जो फिर से प्रतिरूपकता और संरचना को नुकसान पहुंचाता है।
POSIX गोले में निश्चित रूप से और कम से कम - बाद में इसके समाधान हैं bash
, लेकिन यह आपको ऊपर बिंदु 1 पर वापस लाता है।ksh93
zsh
आप GNU ऑटोकॉन्फ मैक्रो लेखन पर स्टाइल गाइड में इसका प्रभाव देख सकते हैं, जहां वे अनुशंसा करते हैं कि आप स्वयं मैक्रो के नाम के साथ चर नाम उपसर्ग करें, जो बहुत लंबे समय तक वेरिएबल नामों को शुद्ध रूप से समीपता से टक्कर की संभावना को कम करने के लिए अग्रणी करते हैं। शून्य।
यहां तक कि सी इस स्कोर पर एक मील तक बेहतर है। न केवल अधिकांश सी प्रोग्राम मुख्य रूप से फ़ंक्शन-स्थानीय चर के साथ लिखे गए हैं, सी ब्लॉक स्कूपिंग का भी समर्थन करता है, जिससे एक ही फ़ंक्शन के भीतर कई ब्लॉकों को क्रॉस-संदूषण के बिना चर नामों का पुन: उपयोग करने की अनुमति मिलती है।
शेल प्रोग्रामिंग भाषाओं में कोई मानक पुस्तकालय नहीं है।
यह तर्क करना संभव है कि एक शेल स्क्रिप्टिंग भाषा की मानक लाइब्रेरी की सामग्री है PATH
, लेकिन यह सिर्फ इतना कहती है कि परिणाम के कुछ भी प्राप्त करने के लिए, एक शेल स्क्रिप्ट को दूसरे पूरे कार्यक्रम के लिए कॉल करना होगा, शायद एक और अधिक शक्तिशाली भाषा में लिखा गया है। से शुरू।
पर्ल के सीपीएएन के साथ न तो शेल उपयोगिता पुस्तकालयों का व्यापक रूप से उपयोग किया जाने वाला संग्रह है । तृतीय-पक्ष उपयोगिता कोड की एक बड़ी उपलब्ध लाइब्रेरी के बिना, एक प्रोग्रामर को हाथ से अधिक कोड लिखना होगा, इसलिए वह कम उत्पादक है।
यहां तक कि तथ्य यह है कि सबसे शेल स्क्रिप्ट बाहरी प्रोग्राम आमतौर पर सी में लिखे पर भरोसा करते हैं कुछ भी उपयोगी किया पाने के लिए अनदेखी, वहाँ उन सभी की भूमि के ऊपर है pipe()
→ fork()
→ exec()
कॉल जंजीरों। अन्य OSes पर IPC और लॉन्च करने की प्रक्रिया की तुलना में यह पैटर्न यूनिक्स पर काफी कुशल है , लेकिन यहां यह प्रभावी रूप से प्रतिस्थापित कर रहा है कि आप एक अन्य स्क्रिप्टिंग भाषा में एक सबरूटीन कॉल के साथ क्या करेंगे , जो अभी भी अधिक कुशल है। यह शेल स्क्रिप्ट निष्पादन गति की ऊपरी सीमा पर एक गंभीर टोपी लगाता है।
शेल स्क्रिप्ट में समानांतर निष्पादन के माध्यम से अपने प्रदर्शन को बढ़ाने की क्षमता बहुत कम होती है।
बॉर्न के गोले हैं &
, wait
और इसके लिए पाइपलाइन, लेकिन यह मुख्य रूप से केवल कई कार्यक्रमों की रचना के लिए उपयोगी है, सीपीयू या आई / एस समानांतरता को प्राप्त करने के लिए नहीं। आप पूरी तरह से शेल स्क्रिप्टिंग के साथ कोर को पेग या संतृप्त करने में सक्षम होने की संभावना नहीं रखते हैं , और यदि आप ऐसा करते हैं, तो आप शायद अन्य भाषाओं में बहुत अधिक प्रदर्शन प्राप्त कर सकते हैं।
विशेष रूप से पाइपलाइन समानांतर निष्पादन के माध्यम से प्रदर्शन को बढ़ाने के कमजोर तरीके हैं। यह केवल दो कार्यक्रमों को समानांतर में चलने देता है, और दोनों में से एक को संभवतः I / O पर या किसी भी समय किसी अन्य बिंदु से अवरुद्ध किया जाएगा ।
इसके चारों ओर बाद के तरीके हैं, जैसे कि xargs -P
और जीएनयूparallel
, लेकिन यह सिर्फ ऊपर 4 बिंदु तक जाता है।
मल्टी-प्रोसेसर सिस्टम का पूर्ण लाभ उठाने की क्षमता के साथ प्रभावी रूप से, शेल स्क्रिप्ट हमेशा एक भाषा में एक अच्छी तरह से लिखे गए प्रोग्राम की तुलना में धीमी होने वाली हैं जो सिस्टम में सभी प्रोसेसर का उपयोग कर सकती हैं। जीएनयू ऑटोकॉन्फ़ configure
स्क्रिप्ट का उदाहरण फिर से लेने के लिए, सिस्टम में कोर की संख्या को दोगुना करना उस गति को सुधारने के लिए बहुत कम करेगा जिस पर वह चलता है।
शेल स्क्रिप्टिंग भाषाओं में संकेत या संदर्भ नहीं होते हैं ।
यह आपको अन्य प्रोग्रामिंग भाषाओं में आसानी से किए गए चीजों का एक समूह बनाने से रोकता है।
एक बात के लिए, प्रोग्राम की मेमोरी में किसी अन्य डेटा संरचना के लिए अप्रत्यक्ष रूप से संदर्भित करने में असमर्थता का मतलब है कि आप अंतर्निहित डेटा संरचनाओं तक सीमित हैं । आपके शेल में साहचर्य सरणियाँ हो सकती हैं , लेकिन वे कैसे कार्यान्वित की जाती हैं? कई संभावनाएं हैं, प्रत्येक अलग - अलग ट्रेडऑफ्स के साथ: लाल-काले पेड़ , एवीएल पेड़ , और हैश टेबल सबसे आम हैं, लेकिन अन्य हैं। यदि आपको ट्रेडऑफ के एक अलग सेट की आवश्यकता है, तो आप फंस गए हैं, क्योंकि संदर्भों के बिना, आपके पास कई प्रकार की उन्नत सामग्री संरचनाओं को हाथ से रोल करने का तरीका नहीं है। आपको जो दिया गया था, उससे आप चिपके हुए हैं।
या, यह ऐसा मामला हो सकता है कि आपको एक डेटा संरचना की आवश्यकता होती है , जिसमें आपके शेल स्क्रिप्ट दुभाषिया में निर्मित पर्याप्त विकल्प भी नहीं होता है, जैसे कि एक निर्देशित चक्रीय ग्राफ , जिसे आपको एक निर्भरता ग्राफ को मॉडल करने की आवश्यकता हो सकती है । मैं दशकों से प्रोग्रामिंग कर रहा हूं, और एकमात्र तरीका है कि मैं ऐसा करने के लिए सोच सकता हूं कि शेल स्क्रिप्ट में फ़ाइल सिस्टम को दुरुपयोग करना होगा , जिसमें नकली संदर्भों के रूप में सिमिलिंक का उपयोग किया जाएगा। जब आप केवल ट्यूरिंग-पूर्णता पर भरोसा करते हैं, तो आपको इस तरह का समाधान मिलता है, जो आपको इस बारे में कुछ नहीं बताता है कि समाधान सुरुचिपूर्ण, तेज या समझने में आसान है।
उन्नत डेटा संरचनाएं संकेत और संदर्भ के लिए केवल एक उपयोग हैं। कर रहे हैं उनके लिए अन्य अनुप्रयोगों के ढेर , जो केवल आसानी से एक बॉर्न परिवार खोल पटकथा भाषा में नहीं किया जा सकता है।
मैं आगे और आगे बढ़ सकता था, लेकिन मुझे लगता है कि आप यहाँ बिंदु प्राप्त कर रहे हैं। सीधे शब्दों में कहें, यूनिक्स प्रकार प्रणालियों के लिए कई और अधिक शक्तिशाली प्रोग्रामिंग भाषाएं हैं।
आपको शायद GNU Autoconf के डेवलपर्स की तुलना में अत्यधिक पोर्टेबल बॉर्न शेल बोली में लिखने की उपयोगिता में विश्वासियों का एक बड़ा समूह नहीं मिलेगा, फिर भी उनकी खुद की रचना मुख्य रूप से पर्ल में लिखी गई है, साथ ही कुछ m4
और केवल शेल का एक छोटा सा स्क्रिप्ट; केवल Autoconf का आउटपुट शुद्ध बॉर्न शेल स्क्रिप्ट है। अगर यह सवाल नहीं है कि "बॉर्न हर जगह" अवधारणा कितनी उपयोगी है, तो मुझे नहीं पता कि क्या होगा।
लेकिन यह वही बात नहीं है जो यह कहती है कि मनमाने ढंग से-बड़ी शेल स्क्रिप्ट लिखना सुखद है, डिबग करना आसान है, या निष्पादित करने के लिए तेज़ है।
एक बार जब आप शेल स्क्रिप्टिंग का उपयोग करने के तरीके के बारे में बात करना शुरू कर देते हैं, जैसा कि अन्य कार्यक्रमों को चलाने के लिए गोंद के रूप में होता है PATH
, तो दरवाजे खुल जाते हैं, क्योंकि अब आप केवल अन्य प्रोग्रामिंग भाषाओं में ही किया जा सकता है, जो आपको कहना है सीमा बिल्कुल नहीं है। एक खोल स्क्रिप्ट है कि में अन्य कार्यक्रमों के लिए बाहर फोन करके अपनी शक्ति के सभी हो जाता है PATH
के रूप में तेजी से और अधिक शक्तिशाली भाषाओं में लिखे गए अखंड कार्यक्रमों के रूप में नहीं चलता है, लेकिन यह करता है चलाते हैं।
और यही बात है। यदि आपको तेजी से दौड़ने के लिए एक कार्यक्रम की आवश्यकता है, या यदि उसे दूसरों से उधार लेने की शक्ति के बजाय अपने आप में शक्तिशाली होने की आवश्यकता है, तो आप इसे शेल में नहीं लिखते हैं।
मैं बड़ी संख्या में प्रोग्रामिंग का समर्थन करने के लिए आवश्यक सुविधाओं की सूची में लगभग 20 वें स्थान पर डिबगिंग टूल सपोर्ट डालूंगा। प्रोग्रामर की एक पूरी बहुत उचित डिबगर्स की तुलना में printf()
डिबगिंग पर बहुत अधिक निर्भर करती है , भाषा की परवाह किए बिना।
sh
स्क्रिप्टconfigure
जो एक महान कई संयुक्त राष्ट्र * x संकुल के लिए निर्माण प्रक्रिया के हिस्से के रूप में किया जाता है 'अपेक्षाकृत सरल' नहीं है।