एक शेल ऑपरेटिंग सिस्टम के लिए एक इंटरफ़ेस है। यह आमतौर पर अपने आप में एक अधिक या कम मजबूत प्रोग्रामिंग भाषा है, लेकिन विशेष रूप से ऑपरेटिंग सिस्टम और फाइल सिस्टम के साथ बातचीत करने में आसान बनाने के लिए डिज़ाइन की गई सुविधाओं के साथ। POSIX शेल का (इसके बाद केवल "शेल" के रूप में संदर्भित) शब्दार्थ एक उत्परिवर्तन का एक सा है, LISP की कुछ विशेषताओं (एस-भावों में शेल शब्द विभाजन के साथ बहुत कुछ है ) और सी (शेल के अंकगणित वाक्यविन्यास का बहुत कुछ है) शब्दार्थ सी से आता है)।
शेल के सिंटैक्स की दूसरी जड़ इसकी परवरिश से अलग-अलग UNIX उपयोगिताओं की एक मिशमा के रूप में आती है। शेल में अक्सर निर्मित होने वाले अधिकांश वास्तव में बाहरी आदेशों के रूप में लागू किए जा सकते हैं। यह लूप के लिए कई शेल नियोफाइट्स फेंकता है जब उन्हें पता चलता है कि /bin/[
कई प्रणालियों पर मौजूद है।
$ if '/bin/[' -f '/bin/['; then echo t; fi
t
वाट?
यह बहुत अधिक समझ में आता है यदि आप देखते हैं कि एक शेल कैसे लागू किया जाता है। यहाँ एक कार्यान्वयन है जो मैंने एक अभ्यास के रूप में किया था। यह पायथन में है, लेकिन मुझे उम्मीद है कि यह किसी के लिए हैंगअप नहीं है। यह बहुत मजबूत नहीं है, लेकिन यह शिक्षाप्रद है:
#!/usr/bin/env python
from __future__ import print_function
import os, sys
'''Hacky barebones shell.'''
try:
input=raw_input
except NameError:
pass
def main():
while True:
cmd = input('prompt> ')
args = cmd.split()
if not args:
continue
cpid = os.fork()
if cpid == 0:
os.execl(args[0], *args)
else:
os.waitpid(cpid, 0)
if __name__ == '__main__':
main()
मुझे आशा है कि ऊपर स्पष्ट है कि शेल का निष्पादन मॉडल बहुत अधिक है:
1. Expand words.
2. Assume the first word is a command.
3. Execute that command with the following words as arguments.
विस्तार, कमान संकल्प, निष्पादन। शेल के सभी शब्दार्थ इन तीन चीजों में से एक में बंधे हुए हैं, हालांकि वे कार्यान्वयन के मुकाबले कहीं अधिक समृद्ध हैं जो मैंने ऊपर लिखा था।
सभी कमांड नहीं fork
। वास्तव में, कुछ मुट्ठी भर आदेश ऐसे होते हैं जो बाह्य रूप में लागू किए गए एक टन का अर्थ नहीं करते हैं (जैसे कि उन्हें करना होगा fork
), लेकिन यहां तक कि वे अक्सर सख्त पॉसिक्स अनुपालन के लिए बाह्य के रूप में उपलब्ध होते हैं।
बैश ने POSIX शेल को बढ़ाने के लिए नई विशेषताओं और कीवर्ड को जोड़कर इस आधार का निर्माण किया। यह श के साथ लगभग संगत है, और बैश इतना सर्वव्यापी है कि कुछ स्क्रिप्ट लेखकों को यह एहसास किए बिना वर्षों चले जाते हैं कि स्क्रिप्ट वास्तव में पोस्किली सख्त प्रणाली पर काम नहीं कर सकती है। (मुझे यह भी आश्चर्य है कि लोग एक प्रोग्रामिंग भाषा के शब्दार्थ और शैली के बारे में इतना कैसे ध्यान रख सकते हैं, और शेल के शब्दार्थ और शैली के लिए बहुत कम हैं, लेकिन मैं विचलन करता हूं।)
मूल्यांकन का आदेश
यह एक ट्रिक प्रश्न है: बैश अपने प्राथमिक सिंटैक्स में अभिव्यक्तियों को बाएं से दाएं की व्याख्या करता है, लेकिन अंकगणितीय सिंटैक्स में यह सी पूर्वता का अनुसरण करता है। अभिव्यक्ति विस्तार से अलग है , यद्यपि। EXPANSION
मार मैनुअल के अनुभाग से:
विस्तार का क्रम है: ब्रेस विस्तार; टिल्ड विस्तार, पैरामीटर और चर विस्तार, अंकगणितीय विस्तार, और कमांड प्रतिस्थापन (बाएं से दाएं फैशन में किया गया); शब्द विभाजन; और pathname विस्तार।
यदि आप वर्डप्लाटिंग, पाथनेम एक्सपेंशन और पैरामीटर विस्तार को समझते हैं, तो आप इस बात को समझने के लिए अपने रास्ते पर हैं कि अधिकांश बैश क्या करता है। ध्यान दें कि वर्डप्लाटिंग के बाद आने वाला पाथनेम का विस्तार महत्वपूर्ण है, क्योंकि यह सुनिश्चित करता है कि उसके नाम पर व्हॉट्सएप वाली फाइल अभी भी एक ग्लोब से मेल खा सकती है। यही कारण है कि ग्लोब विस्तार का अच्छा उपयोग सामान्य रूप से, पार्सिंग कमांड से बेहतर है ।
क्षेत्र
कार्यक्षेत्र गुंजाइश
पुराने ECMAscript की तरह, शेल में डायनेमिक स्कोप होता है जब तक कि आप स्पष्ट रूप से किसी फ़ंक्शन के भीतर नामों की घोषणा नहीं करते हैं।
$ foo() { echo $x; }
$ bar() { local x; echo $x; }
$ foo
$ bar
$ x=123
$ foo
123
$ bar
$ …
पर्यावरण और प्रक्रिया "गुंजाइश"
सबस्क्रिप्शन उनके पैरेंट शेल के वेरिएबल को इनहेरिट करता है, लेकिन अन्य प्रकार की प्रक्रियाएं अनएक्सपोर्ट किए गए नामों को प्राप्त नहीं करती हैं।
$ x=123
$ ( echo $x )
123
$ bash -c 'echo $x'
$ export x
$ bash -c 'echo $x'
123
$ y=123 bash -c 'echo $y'
123
आप इन स्कूपिंग नियमों को जोड़ सकते हैं:
$ foo() {
> local -x bar=123
> bash -c 'echo $bar'
> }
$ foo
123
$ echo $bar
$
टंकण अनुशासन
उम, प्रकार। हाँ। बैश वास्तव में प्रकार नहीं है, और सब कुछ एक स्ट्रिंग में फैलता है (या शायद एक शब्द अधिक उपयुक्त होगा।) लेकिन आइए विभिन्न प्रकार के विस्तार की जांच करें।
स्ट्रिंग्स
बहुत कुछ भी एक स्ट्रिंग के रूप में माना जा सकता है। बैश में बेयरिंग्स तार होते हैं जिनका अर्थ पूरी तरह से उस पर लागू विस्तार पर निर्भर करता है।
कोई विस्तार नहीं
यह प्रदर्शित करना सार्थक हो सकता है कि एक नंगे शब्द वास्तव में सिर्फ एक शब्द है, और यह उद्धरण उस बारे में कुछ भी नहीं बदलता है।
$ echo foo
foo
$ 'echo' foo
foo
$ "echo" foo
foo
पदार्थ का विस्तार
$ fail='echoes'
$ set -x
$ "${fail:0:-2}" Hello World
+ echo Hello World
Hello World
विस्तार पर अधिक जानकारी के लिए, Parameter Expansion
मैनुअल के सेक्शन को पढ़ें । यह काफी शक्तिशाली है।
पूर्णांक और अंकगणित के भाव
आप समकोण विशेषता के साथ नाम लिख सकते हैं शेल को असाइनमेंट अभिव्यक्तियों के दाहिने हाथ की तरफ अंकगणित के रूप में बता सकते हैं। फिर, जब पैरामीटर का विस्तार होता है, तो इसे एक स्ट्रिंग ... के विस्तार से पहले पूर्णांक गणित के रूप में मूल्यांकन किया जाएगा।
$ foo=10+10
$ echo $foo
10+10
$ declare -i foo
$ foo=$foo
$ echo $foo
20
$ echo "${foo:0:1}"
2
Arrays
तर्क और स्थितिगत पैरामीटर
सरणियों के बारे में बात करने से पहले यह स्थितिगत मापदंडों पर चर्चा करने के लायक हो सकती है। शेल स्क्रिप्ट की दलीलों को गिने हुए मापदंडों, $1
और $2
, $3
आदि का उपयोग करके एक्सेस किया जा सकता है । आप इन सभी मापदंडों को एक ही बार में उपयोग कर सकते हैं "$@"
, जिसमें विस्तार में सरणियों के साथ कई चीजें हैं। आप की स्थापना की और का उपयोग कर स्थितीय मापदंडों को बदल सकते हैं set
या shift
, या बस खोल या इन मानकों के साथ एक खोल समारोह लागू द्वारा builtins:
$ bash -c 'for ((i=1;i<=$#;i++)); do
> printf "\$%d => %s\n" "$i" "${@:i:1}"
> done' -- foo bar baz
$1 => foo
$2 => bar
$3 => baz
$ showpp() {
> local i
> for ((i=1;i<=$#;i++)); do
> printf '$%d => %s\n' "$i" "${@:i:1}"
> done
> }
$ showpp foo bar baz
$1 => foo
$2 => bar
$3 => baz
$ showshift() {
> shift 3
> showpp "$@"
> }
$ showshift foo bar baz biz quux xyzzy
$1 => biz
$2 => quux
$3 => xyzzy
बैश मैनुअल कभी-कभी $0
एक स्थितिगत पैरामीटर के रूप में भी संदर्भित होता है। मुझे यह भ्रामक लगता है, क्योंकि यह इसे तर्क गिनती में शामिल नहीं करता है $#
, लेकिन यह एक गिना हुआ पैरामीटर है, इसलिए meh। $0
शेल या वर्तमान शेल स्क्रिप्ट का नाम है।
Arrays
सरणियों के सिंटैक्स को स्थितीय मापदंडों के बाद तैयार किया जाता है, इसलिए यदि आप चाहें तो एक बाहरी प्रकार के "बाहरी स्थितीय मापदंडों" के रूप में सरणियों के बारे में सोचना ज्यादातर स्वस्थ है। निम्न दृष्टिकोणों का उपयोग करके ऐरे को घोषित किया जा सकता है:
$ foo=( element0 element1 element2 )
$ bar[3]=element3
$ baz=( [12]=element12 [0]=element0 )
आप सरणी तत्वों को अनुक्रमणिका द्वारा एक्सेस कर सकते हैं:
$ echo "${foo[1]}"
element1
आप ऐरे को स्लाइस कर सकते हैं:
$ printf '"%s"\n' "${foo[@]:1}"
"element1"
"element2"
यदि आप एक सरणी को एक सामान्य पैरामीटर के रूप में मानते हैं, तो आपको शून्य सूचकांक प्राप्त होगा।
$ echo "$baz"
element0
$ echo "$bar"
$ …
यदि आप शब्दों को रोकने के लिए उद्धरण या बैकस्लैश का उपयोग करते हैं, तो सरणी निर्दिष्ट शब्दों को बनाए रखेगा:
$ foo=( 'elementa b c' 'd e f' )
$ echo "${#foo[@]}"
2
सरणियों और स्थितिगत मापदंडों के बीच मुख्य अंतर हैं:
- स्थितिगत पैरामीटर विरल नहीं हैं। यदि
$12
सेट किया गया है, तो आप सुनिश्चित कर सकते हैं कि $11
सेट किया गया है, भी। (यह खाली स्ट्रिंग पर सेट किया जा सकता है, लेकिन $#
12. से छोटा नहीं होगा।) यदि "${arr[12]}"
सेट किया गया है, तो इसकी कोई गारंटी नहीं है कि "${arr[11]}"
सेट किया गया है, और सरणी की लंबाई 1 जितनी हो सकती है।
- किसी सरणी का शून्य तत्व स्पष्ट रूप से उस सरणी का शून्य तत्व है। स्थितिगत मापदंडों में, शून्य तत्व पहला तर्क नहीं है , लेकिन शेल या शेल स्क्रिप्ट का नाम है।
- करने के लिए
shift
एक सरणी, आप टुकड़ा करने के लिए है और पुन: असाइन, की तरह arr=( "${arr[@]:1}" )
। आप भी कर सकते हैं unset arr[0]
, लेकिन यह इंडेक्स 1 में पहला तत्व बना देगा।
- गोलाकार के रूप में शेल फ़ंक्शन के बीच एरे को स्पष्ट रूप से साझा किया जा सकता है, लेकिन आपको इसे देखने के लिए शेल फ़ंक्शन के लिए स्पष्ट रूप से स्थितीय मापदंडों को पास करना होगा।
फ़ाइल नाम के सरणियों को बनाने के लिए पथनाम विस्तार का उपयोग करना अक्सर सुविधाजनक होता है:
$ dirs=( */ )
आदेश
कमांड प्रमुख हैं, लेकिन वे मैनुअल की तुलना में बेहतर गहराई में शामिल हैं। SHELL GRAMMAR
अनुभाग पढ़ें । विभिन्न प्रकार के आदेश हैं:
- साधारण कमांड (जैसे
$ startx
)
- पाइपलाइन (जैसे
$ yes | make config
) (योग्य)
- सूचियाँ (जैसे
$ grep -qF foo file && sed 's/foo/bar/' file > newfile
)
- यौगिक कमांड (जैसे
$ ( cd -P /var/www/webroot && echo "webroot is $PWD" )
)
- Coprocesses (जटिल, कोई उदाहरण नहीं)
- कार्य (एक साधारण कमांड के रूप में माना जा सकता है एक मिश्रित कमांड)
निष्पादन मॉडल
पाठ्यक्रम के निष्पादन मॉडल में ढेर और ढेर दोनों शामिल हैं। यह सभी यूनिक्स कार्यक्रमों के लिए स्थानिक है। बैश में शेल फ़ंक्शन के लिए कॉल स्टैक भी है, जो caller
बिलिन के नेस्टेड उपयोग के माध्यम से दिखाई देता है ।
संदर्भ:
SHELL GRAMMAR
बाश मैनुअल का अनुभाग
- XCU शेल कमांड भाषा प्रलेखन
- बैश गाइड Greycat के विकि पर।
- UNIX पर्यावरण में उन्नत प्रोग्रामिंग
कृपया टिप्पणी करें यदि आप चाहते हैं कि मैं एक विशिष्ट दिशा में और विस्तार करूं।