गूंज कमांड में निर्मित एक शेल क्यों है?


34
$ which echo
echo: shell built-in command.
$ which ls
/bin/ls
$ which cat
/bin/cat

क्यों गूंज की तरह एक स्वतंत्र उपयोगिता नहीं है ls, ps, catआदि? यह विशिष्ट क्यों है? कोई अच्छा कारण?


5
यह ध्यान में रखिए कि यह शैल-विशिष्ट है। ZSH इसे बनाता है, BASH नहीं करता है।
tsvallender

21
@tsv: echoसबसे निश्चित रूप से एक बैश बिलिन है । वास्तव में, यह हर बड़े आधुनिक शेल में एक बिलिन है।
अगली सूचना तक रोक दिया गया।

जवाबों:


71

निर्मितियों के दो वर्ग हैं:

  1. कुछ कमांड को शेल प्रोग्राम में ही बनाया जाना चाहिए क्योंकि वे बाहरी होने पर काम नहीं कर सकते हैं।

    cdएक ऐसा है जब से यह बाहरी थे, यह केवल अपनी खुद की निर्देशिका बदल सकता है; यह शेल की वर्तमान कार्यशील निर्देशिका को प्रभावित नहीं कर सकता है। (यह भी देखें: एक कार्यक्रम क्यों cdनहीं है? )

  2. कमांड के अन्य वर्ग को दक्षता के लिए शुद्ध रूप से शेल में बनाया गया है।

    आदमी पेज जो उल्लेख builtins पर एक अनुभाग है , और इस वर्ग में के रूप में आदेशों का उदाहरण।dash printfechotest

यूनिक्स सिस्टम ने हमेशा उस दूसरी श्रेणी के कमांड के लिए अलग-अलग निष्पादनयोग्य शामिल किए हैं। ये अलग-अलग निष्पादनयोग्य अभी भी मेरे द्वारा उपयोग किए जाने वाले हर यूनिक्स सिस्टम पर उपलब्ध हैं, भले ही वे आपके द्वारा उपयोग किए जाने वाले प्रत्येक शेल में निर्मित हों। ( POSIX को वास्तव में आवश्यकता है कि ये निष्पादक मौजूद हों।)

मेरा मानना ​​है कि echoएटी एंड टी यूनिक्स सिस्टम वी रिलीज़ 3.1 में शेल में बनाया गया है। मैं एटी एंड टी 3 बी 1 श्रृंखला यूनिक्स सिस्टम के लिए मैनुअल के दो अलग-अलग संस्करणों की तुलना पर आधारित हूं । किसी ने इन पुस्तिकाओं के 1986 संस्करणों को स्कैन करके उन्हें ऑनलाइन डाल दिया है ; ये SVR3 की मूल रिलीज़ के अनुरूप हैं। आप देख सकते हैं कि UNIX सिस्टम V के उपयोगकर्ता नियमावली, खंड II केecho पृष्ठ 523 पर सूची में नहीं है , जहां आप यह उम्मीद करेंगे कि यदि कमांड शेल में बनाया गया था। 1987 से SVR3.1 मैनुअल के अपने स्थानीय समाचार पत्र की नकल में, है मैनुअल के इस खंड में सूचीबद्ध।echo

मुझे पूरा यकीन है कि यह बर्कले CSRG नवाचार नहीं है जो AT & T घर वापस लाए। 4.3BSD उसी वर्ष SVR3, 1986 के रूप में सामने आया, लेकिन यदि आप 4.3BSD के sh.1 मैनपेज को देखते हैं, तो आप देखते हैं कि echo"स्पेशल कमांड" खंड में अंतर्निहित कमांड की सूची नहीं है। यदि CSRG ने ऐसा किया, तो हमें यह साबित करने के लिए एक प्रलेखित स्रोत चाहिए।

इस बिंदु पर, आपको आश्चर्य हो सकता है कि अगर echoSVR3.1 की तुलना में पहले शेल में बनाया गया था और इस तथ्य को तब तक दस्तावेज नहीं किया गया था । मेरे लिए उपलब्ध नवीनतम प्री-एसवीआर 3 एटी एंड टी यूनिक्स स्रोत कोड पीडीपी -11 सिस्टम III टारबॉल में है , जिसमें आपको बॉर्न शेल स्रोत कोड मिलेगा। आपको echoअंतर्निहित कमांड तालिका नहीं मिलेगी , जो कि अंदर है /usr/src/cmd/sh/msg.c। उस फ़ाइल में टाइमस्टैम्प के आधार पर, जो साबित करता है कि echoनिश्चित रूप से 1980 में शेल में नहीं था।


सामान्य ज्ञान

उसी निर्देशिका में एक फ़ाइल भी होती है, builtin.cजिसमें इस प्रश्न के लिए कुछ भी नहीं होता है, लेकिन हमें यह दिलचस्प टिप्पणी मिलती है:

/*      
    builtin commands are those that Bourne did not intend
    to be part of his shell.
    Redirection of i/o, or rather the lack of it, is still a
    problem..
*/      

SysV UM के पृष्ठ 385 पर, वॉल्यूम II जिसका आपने उल्लेख किया है, printksh के लिए अंतर्निहित कमांड है जिसे कहा जाता है कि जैसा व्यवहार करना है echo। यह कमांड ISC से भी AT & T Unix SVR4 2.1 i386 की तरह मौजूद है। print "\012"प्रतिध्वनि के रूप में एक ही परिणाम देता है। आश्चर्य है कि ksh में क्यों प्रिंट हुआ था और ईको बिल्ट नहीं था? वैसे भी वास्तव में दिलचस्प है।

कुछ साल पहले के ऐसे कितने रत्न हैं, जो 2016 में एक एडिट द्वारा अनसुनी किए जाने की प्रतीक्षा में थे? +1
इरुवर

+1। धन्यवाद। क्या आप मेरे (व्यवस्थित) पढ़ने / सीखने के लिए एक कमांड बिल्टिन बनाने के उद्देश्य से स्रोत (संदर्भ) प्रदान कर सकते हैं?
टिम

मैं व्यवस्थित रूप से पढ़ने या सीखने के लिए कुछ संदर्भ, मैनुअल या मानक खोजना चाहता हूं। मैंने इसे बैश संदर्भ मैनुअल, और POSIX विनिर्देशों में देखने की कोशिश की। लेकिन मुझे यह नहीं मिल रहा है। मुझे यकीन नहीं है कि मैं उन्हें याद करूंगा।
टिम

@ समय: जैसा कि यहां और अन्य उत्तर बताते हैं, कुछ कमांड शेल में बनाए जाने चाहिए या वे अपना काम नहीं कर सकते। अन्य सभी विशुद्ध रूप से वैकल्पिक हैं । यही अनिवार्य रूप से मेरे बॉर्न शेल स्रोत स्निपेट ऊपर, वास्तव में कहता है। चूंकि शेल में इस तरह के कमांड का निर्माण वैकल्पिक है, इसलिए एक आधिकारिक तर्क केवल एक कार्यान्वयनकर्ता की राय दे सकता है।
वॉरेन यंग

19

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

कभी-कभी एक सिस्टम इतना टूट जाता है कि lsकमांड काम नहीं करता है। कुछ मामलों में, एक echo *इच्छा अभी भी काम करेगी।

एक और (अधिक महत्वपूर्ण!) उदाहरण है kill: यदि कोई प्रणाली नि: शुल्क पीआईडी ​​से बाहर निकलती है, तो उसे चलाना संभव नहीं है /bin/kill(क्योंकि इसके लिए पीआईडी ​​:-) की आवश्यकता होती है, लेकिन अंतर्निहित killकाम करेगा।

Btw।, whichएक बाहरी कमांड है (कम से कम यह बाश में आंतरिक नहीं है), इसलिए यह आंतरिक कमांड को सूचीबद्ध नहीं कर सकता है। उदाहरण के लिए:

$ which echo
/bin/echo
$ type -a echo
echo is a shell builtin
echo is /bin/echo

यह मत भूलो कि लगभग सभी बाहरी निष्पादनयोग्य लाइब्रेरी फ़ाइलों पर निर्भर हैं। कभी-कभी तबाही होती है और उन पुस्तकालयों को लोड नहीं किया जा सकता है (सलाह: कभी भी जारी ldconfigन करें जब तक आपको पता नहीं है कि आप क्या कर रहे हैं)। इसके अलावा, क्या होगा अगर आप अपने / बिन, या बदतर, अपने / एसबीएन विभाजन को उड़ा देते हैं, लेकिन फिर भी एक शेल भरा हुआ है?
LawrenceC

यदि आप पीआईडी ​​से बाहर भागते हैं तो यह पता लगाना मुश्किल हो सकता है कि आप किस पीआईडी ​​को मारना चाहते हैं। आप एक psकमांड नहीं चला सकते हैं , इसलिए आपको पीआईडी ​​को मैन्युअल रूप से ढूंढना होगा /proc
कास्परड

हालांकि (कम से कम) सेंटोस whichएक बैश उर्फ ​​है जो alias | /usr/bin/which --read-alias ...बाहरी रूप से चलता है इसलिए उपनामों की पहचान which कर सकता है (लेकिन अभी भी नहीं बनाया गया है)। मैं तय नहीं कर सकता कि इस शानदार या विकृत पर विचार करें।
dave_thompson_085

इस बिंदु पर कि ls कमांड अब काम नहीं करता है, मुझे लगता है कि आपको बूट / मास्टर के बजाय ड्राइव को दास के रूप में माउंट करना चाहिए और उस तरह से फ़ाइल संरचना को ठीक करना चाहिए। मुझे यकीन नहीं है कि आप सिस्टम भ्रष्टाचार की उस सीमा को प्रतिध्वनि के साथ ठीक कर सकते हैं जब तक कि आप गूंज> फ़ाइल में नहीं हैं और इसे ठीक करने में लंबा समय लगेगा। दी है कि आप एक बैश स्क्रिप्ट लिख सकते हैं जो सिस्टम संरचना को ठीक करने के लिए थी।
jonnyjandles

13

बैश रेफरेंस मैनुअल के अनुसार , यह सुविधा के बारे में है।

शेल अलग-अलग उपयोगिताओं के माध्यम से प्राप्त करने के लिए असंभव या असुविधाजनक कार्यशीलता को लागू करने वाले अंतर्निहित आदेशों (अंतर्निहित) का एक छोटा सा सेट भी प्रदान करते हैं। उदाहरण के लिए, cd, break, जारी, और निष्पादित) शेल के बाहर लागू नहीं किया जा सकता है क्योंकि वे सीधे शेल को ही हेरफेर करते हैं। अन्य लोगों के बीच इतिहास, गेटअप, किल, या पीडब्ल्यूडी निर्मित, को अलग-अलग उपयोगिताओं में लागू किया जा सकता है, लेकिन वे बिलिन कमांड के रूप में उपयोग करने के लिए अधिक सुविधाजनक हैं। सभी शेल बिल्डरों का वर्णन बाद के खंडों में किया गया है।

उन्नत बैश पटकथा गाइड एक अधिक विस्तृत विवरण दिया गया है:

"एक बेसिन बैश टूल सेट के भीतर निहित एक कमांड है, जो वास्तव में बनाया गया है। यह या तो प्रदर्शन कारणों के लिए है - बिल्डरों को बाहरी कमांड की तुलना में तेजी से निष्पादित किया जाता है, जिसे आमतौर पर 1 अलग प्रक्रिया के लिए फोर्किंग की आवश्यकता होती है - या क्योंकि किसी विशेष बिल्डिन को प्रत्यक्ष की आवश्यकता होती है शेल इंटर्नल्स तक पहुंच। "

यह भी ध्यान दें कि echoकुछ प्रणालियों पर एक स्टैंडअलोन उपयोगिता के रूप में मौजूद है। यहाँ मैं अपने डार्विन प्रणाली (MacOSX 10.5.8 - तेंदुए) पर क्या कर रहा हूँ

$ uname -a
Darwin host.foo.org 9.8.0 Darwin Kernel Version 9.8.0: Wed Jul 15 16:55:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE_I386 i386
$ bash --version
GNU bash, version 3.2.17(1)-release (i386-apple-darwin9.0)
Copyright (C) 2005 Free Software Foundation, Inc.
$ which echo
/bin/echo

echoबिल्टिन के रूप में भी उपलब्ध है, लेकिन जाहिर तौर पर मेरी स्क्रिप्ट्स मेरे मैक पर / बिन / इको का उपयोग करती हैं, और मेरे अधिकांश लिनक्स और फ्रीबीएसडी सिस्टमों पर बैश बिलिन का उपयोग करती हैं। लेकिन यह महत्वपूर्ण नहीं है, क्योंकि स्क्रिप्ट अभी भी हर जगह ठीक काम करती है।


3
शेल-इन-इन्स की बात करते हुए, आपको "जो" के बजाय "टाइप" का उपयोग करना चाहिए।
टेडी

धन्यवाद @ टेडी मैंने वो करना शुरू कर दिया है, जब मुझे याद है। जीवन बहुत बेहतर है धन्यवाद type
स्टीफन लासिवस्की

6

Bhm के उत्तर के पूरक के लिए, मान लीजिए कि /binगलती से आपको हटा दिया गया था PATH। आप इसे echo $PATHढूंढने में सक्षम होना चाहेंगे , है ना?


2

हालांकि अधिकांश गोले में एक अंतर्निहित में शामिल echoहै, GNU CoreUtils में एक स्वसंपूर्ण कार्यान्वयन भी शामिल है:

$ which echo
/bin/echo
$ dpkg -S /bin/echo
coreutils: /bin/echo

ऐसा लगता है कि आपके पास GNU Coreutils स्थापित नहीं है (अधिकांश लिनक्स-आधारित डेस्कटॉप और सर्वर OS ने इसे डिफ़ॉल्ट रूप से स्थापित किया है, लेकिन एम्बेडेड लिनक्स या अन्य UNIX इसके बजाय शेल उपयोगिताओं के वैकल्पिक संग्रह का उपयोग कर सकते हैं)।

BTW: यदि आप बिजीबॉक्स को देखते हैं, तो आप देखेंगे कि ls, psऔर catवहाँ अंतर्निहित कमांड भी हैं (या कम से कम हो सकता है; इसका उपयोग एम्बेडेड सिस्टम के लिए किया जाता है और ज़रूरत की हर चीज़ को नहीं छोड़ा जा सकता है)।


3
मूल पोस्टर के परीक्षण उस परिकल्पना का समर्थन नहीं करते हैं जो /bin/echoमौजूद नहीं है। वे सिर्फ दिखाते हैं कि बिल्ट echoने PATH में किसी भी कार्यक्रम के लिए पूर्वता लिया है ।
वॉरेन यंग

1

यहाँ वास्तविक कारण है कि echoशेल शेल क्यों होना चाहिए:

मान लीजिए कि आपके पास एक पासवर्ड है $PASSWORD। आप इसे किसी फ़ाइल में कैसे लिखते हैं ./password? स्वाभाविक रूप से अधिकांश प्रोग्रामर लिखेंगे:

echo "$PASSWORD" >./password

हालाँकि, यदि echoशेल निर्मित नहीं होता है, तो पासवर्ड सभी उपयोगकर्ताओं के लिए psसूचना के माध्यम से लीक हो जाएगा ।

बेशक, यदि आप इसके बारे में चतुर होना चाहते हैं, तो आप बिना पासवर्ड के स्टोर करने का एक तरीका खोज सकते हैं echo, शायद कुछ अन्य शेल फीचर का शोषण कर रहे हैं:

cat >./password <<EOF
${PASSWORD}
EOF

हालाँकि, echoएक बिल्डिन के रूप में एक महत्वपूर्ण सीटबेल्ट है क्योंकि किसी फ़ाइल को पासवर्ड बचाने के लिए सबसे स्पष्ट तरीका भी काम करना चाहिए।


3
जबकि एक उपयोगी साइड इफेक्ट मुझे यह बेहद संदिग्ध लगता है कि यही कारण था।
प्लग

@DepressedDaniel: क्या आपको वापस करना है? आपके उत्तर का समर्थन करने के लिए आपने कहाँ संदर्भ दिया है?
जोकर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.