एक / बिन / गूंज क्यों है और मैं इसका उपयोग क्यों करना चाहूंगा?


52

मैंने देखा कि /bin/echoमेरे उबंटू मेट 17.04 सिस्टम पर एक द्विआधारी निष्पादन योग्य है।

मैंने सोचा, यह अजीब है, क्योंकि

$ type echo
echo is a shell builtin

Cursory परीक्षण बताता है कि /bin/echoबैश बिलिन के समान ही काम करता है echo:

$ /bin/echo foo
foo
$ /bin/echo $USER
zanna

तो, echoबैश कार्यक्रम से अलग होने का एक और संस्करण क्यों है , और मैं इसका उपयोग क्यों और कब करना चाहूंगा?



2
@ bodhi.zazen यह काफी उपयोगी है, भले ही यह समान नहीं है, क्योंकि यह इस प्रश्न के बारे में बताता है। यह प्रश्न पूछता है कि echoशेल बिलियन के रूप में क्यों प्रदान किया गया है, जबकि यह एक पूछता है कि इसे बाहरी कमांड के रूप में क्यों प्रदान किया गया है।
एलिया कगन

3
एक कारण यह है कि हर कोई बैश का उपयोग नहीं करता है। मुझे लगता है कि / बिन / इको बैश पूर्ववर्ती है, और डेवलपर्स ने इसे निष्पादन योग्य का उपयोग करने के बजाय अंतर्निहित के रूप में शामिल करने के लिए उपयोगी / कुशल पाया।
jamesqf

जवाबों:


88

यदि आप एक bashप्रॉम्प्ट खोलते हैं और echoकमांड में टाइप करते हैं , जो रनिंग के बजाय शेल बिलिन का उपयोग करता है /bin/echo। इसके /bin/echoअस्तित्व के लिए अभी भी कारण महत्वपूर्ण हैं:

  1. आप हमेशा शेल का उपयोग नहीं कर रहे हैं। विभिन्न परिस्थितियों में, आप एक निष्पादन योग्य को सीधे चलाते हैं, शेल के माध्यम से नहीं।
  2. कम से कम सिद्धांत में, कुछ गोले में एक echoबेसिन नहीं होता है । यह वास्तव में आवश्यक नहीं है।

# 1 पर विस्तार करने के लिए, आप सभी नियमित फ़ाइलें हैं जिनके नाम के साथ शुरू किया जाना चाहते थे लगता है abcकहीं srcके dest। ऐसा करने के कई तरीके हैं लेकिन उनमें से एक है:

find src -name 'abc*' -type f -exec mv -nv {} dest/ \;

लेकिन मान लीजिए, केवल दौड़ने के बजाय, आप हर उस कमांड को देखना चाहते हैं जो पहले चलाया जाएगा। ठीक है, तो आप echoकमांड को पूर्व निर्धारित कर सकते हैं , जैसा कि आप अन्य संदर्भों में कर सकते हैं:

find src -name 'abc*' -type f -exec echo mv -nv {} dest/ \;

लेकिन findएक खोल का उपयोग नहीं करता है। जो चलता है /bin/echo

इसके अलावा findके साथ -execया-execdir , /bin/echoनिष्पादन योग्य अन्य कार्यक्रमों कि खुद प्रोग्राम को चलाने लेकिन एक खोल के माध्यम से नहीं द्वारा बुलाया जाएगा। यह होता है के साथ xargsआदेश (जो संबंधित है के लिए find), और साथ ही इस तरह के रूप अन्य संदर्भों की एक संख्या में लाइन की एक फ़ाइल । एक और उदाहरण जब आप चलाते हैं , जो काम कर रहा है तो परीक्षण के लिए आसान हो सकता है।Exec=.desktopsudo echosudo

इसी तरह, कुछ गोले में एक printfबिल्डिन होता है, लेकिन /usr/bin/printfयह भी मौजूद होता है।

एक कम सामान्य संभावित कारण जिसे आप जानबूझकर उपयोग कर सकते हैं /bin/echo, यदि आप इसके बीच के अंतर और echoआपके शेल द्वारा प्रदान किए गए आदेश पर भरोसा कर रहे हैं । man echoदस्तावेज /bin/echo; बिलिन help echoमें bash दस्तावेजों bashechoबहुत पोर्टेबल नहीं है, क्योंकि अलग-अलग कार्यान्वयन - दोनों ऑपरेटिंग सिस्टम पर और एक ही ऑपरेटिंग सिस्टम पर गोले में - विभिन्न विकल्पों (जैसे, -e) का समर्थन करते हैं और बैकस्लैश के उनके उपचार में भिन्न होते हैं । बेशक, ऐसे विवरणों पर भरोसा करने से बचना बेहतर है, और printfइसके बजाय उपयोग करें , जो कहीं अधिक पोर्टेबल है

में bash, आप कर सकते हैं typebuiltin शो /bin/echoके रूप में अच्छी तरह से - यह सोचते /binहै अपने $PATHरूप में यह हमेशा होना चाहिए - द्वारा इसे पारित -aझंडा :

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

21
और यह भी क्योंकि POSIX विनिर्देश कहता है कि एक होना चाहिए।
ग्लेन जैकमैन

4
@glennjackman मैं उम्मीद कर रहा था कि कोई व्यक्ति उस बारे में उत्तर देगा, वास्तव में, और मुझे आशा है कि आप ऐसा करने का निर्णय लेंगे! वहाँ कुछ सूक्ष्मता शामिल है, हालांकि, न तो डेबियन, उबंटू, और न ही GNU Coreutils (और न ही GNU परियोजना) कुल मिलाकर POSIX का पालन करने की कोशिश करते हैं । उदाहरण के लिए, POSIX एक cdनिष्पादन योग्य अस्तित्व को जोर देता है (जो, जब चलाया जाता है, निर्देशिका को बदलता है और छोड़ता है, तो कॉलर को छोड़कर जहां वे पहले थे) और कुछ OSes में एक है। यह जीएनयू मानकों में 4.1 का हवाला देते हुए मददगार हो सकता है ।
एलियाह कगन

@EliahKagan: Incidentaly / usr / bin / cd में एक उपयोग है: / usr / bin / cd निर्देशिका कमांड उस निर्देशिका में कमांड चलाता है। यदि निर्देशिका परिवर्तन विफल रहता है तो कमांड शुरू नहीं होता है।
जोशुआ

4
@ जोशुआ का एक बेहतर उपयोग cdकिसी दिए गए निर्देशिका तक पहुंचने की क्षमता के परीक्षण के रूप में है: यदि /usr/bin/cd some/dirसफल होता है, तो एक शॉट में आपने परीक्षण किया है: ए) जो some/dirमौजूद है, बी) यह एक निर्देशिका या एक से लिंक है, और सी) उस निर्देशिका तक पहुँचने के लिए आपके लिए आवश्यक अनुमतियां मौजूद हैं; सब अपनी अपनी अवस्था बदले बिना।
मुरु

1
@CarlWitthoft, देखें कि प्रिंट ईको से बेहतर क्यों है? इसके अलावा, यह /bin/echoनहीं है \bin\echo, जब तक आप विंडोज का उपयोग नहीं कर रहे हैं। ;)
वाइल्डकार्ड

31

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

सही सवाल यह है: यह पहली जगह में बिलियन क्यों है , जब यह पूरी तरह से ठीक बाहरी कमांड हो सकता है (और है)?

सादगी के लिए, डैश में निर्मित घरों पर एक नज़र डालें, एक खसरा 38 (बाश में 61 है, तुलना के लिए, उत्पादन से जा रहा है compgen -b):

.               continue        getopts         readonly        type
:               echo            hash            return          ulimit
[               eval            jobs            set             umask
alias           exec            kill            shift           unalias
bg              exit            local           test            unset
break           export          printf          times           wait
cd              false           pwd             trap
command         fg              read            true

इन में से कितने की जरूरत है builtins होने के लिए? [, echo, false, printf, pwd, test, और trueनहीं है की जरूरत है builtins होने के लिए: वे कुछ भी केवल एक builtin कर सकते हैं कि ऐसा नहीं करते हैं (प्रभावित या खोल राज्य कि बाहरी आदेशों के लिए उपलब्ध नहीं है प्राप्त)। बैश का printfकम से कम एक बेसिन होने का लाभ उठाता है: printf -v varआउटपुट को चर में बचाता है vartimebash में भी है खास: एक कीवर्ड होने से, आप bash (डैश के timeबराबर नहीं है ) में कमांड लिस्ट की मनमानी कर सकते हैं । pwdकिसी भी तरह से एक बेसिन होने की आवश्यकता नहीं है - कोई भी बाहरी कमांड वर्तमान वर्किंग डायरेक्टरी को इनहेरिट करने वाला है (और यह एक बाहरी कमांड भी है)।:एक अपवाद है - आपको एनओपी की आवश्यकता है, और :यह है। बाकी ऐसी क्रियाएं करते हैं जो एक बाहरी कमांड आसानी से कर सकती है।

इसलिए, इन बिल्डरों के पांचवे हिस्से को बिल्डिंग्स बनाने की आवश्यकता नहीं है। तो क्यों? मैनपेज * वास्तव में गुजर क्यों इन builtins (जोर मेरा) कर रहे हैं में बताते हैं:dash

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

यह बहुत ज्यादा है: ये बिल्टइन हैं क्योंकि वे अक्सर, अंतःक्रियात्मक और लिपियों में उपयोग किए जाते हैं, और उनकी कार्यक्षमता काफी सरल है, जो शेल काम कर सकता है। और इसलिए यह होता है: कुछ (? सबसे) गोले काम पर ले लिया ** पर वापस जाएं। से 2.9 बीएसडी , और आप एक नहीं मिलेगा builtin।shecho

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


* यह लगभग अल्मोक्विस्ट शेल के लिए संबंधित मैनपेज पाठ के समान है , जो कि डैश, डेबियन अल्मक्विस्ट शेल पर आधारित है।

** zshइस विचार को चरम पर ले जाता है: विभिन्न मॉड्यूल लोड करके आपको मिलने वाली कमांड, जैसे zmv, ऐसी चीजें हैं जिनके बारे में आपको नहीं लगता होगा कि शेल की आवश्यकता है । उस बिंदु पर, असली सवाल यह है: आप ज़ीश के बजाय बैश का उपयोग क्यों करेंगे, जिसमें ये सभी भवन हैं?


1
यह पता चला है कि: एक बिलिन भी होने की जरूरत नहीं है। यह सिर्फ एक मूर्खता नहीं है इसके लिए एक बिल्डिन नहीं है। जब तक आप जल्दी init से बचाव-फ्लॉपी-डिस्क स्तर की समस्याओं (जिस स्थिति में मैंने कठिन तरीके से pwd मज़बूती से काम नहीं करता है) की खोज की है, जब तक कि यह एक बिल्डिन के रूप में नहीं होने के लिए एकमात्र जुर्माना भयानक प्रदर्शन है।
जोशुआ

5
@ जोशुआ नहीं, :एक बाहरी के रूप में वास्तव में एक एनओपी नहीं होगा, आप अभी भी PATHलुकअप, कमांड को निष्पादित करने का प्रयास करेंगे, आदि, जब आप वास्तव में चाहते हैं कि स्पष्ट रूप से कुछ भी नहीं करना है। :जैसा कि एक बिलिन करता है।
मूरू

2
बैश वास्तव pwdमें "तार्किक" पथ ( pwd -L) को दिखाने के डिफ़ॉल्ट व्यवहार के साथ, जिस तरह से काम करता है, उसके लिए इसमें अंतर्निहित होने की आवश्यकता है । /bin/pwdकेवल pwd -Pआपको वास्तविक माता-पिता निर्देशिका दिखाने के व्यवहार को कार्यान्वित कर सकता है , न कि आपके द्वारा cdसंपादित किए जाने वाले सिमलिंक ।
पीटर कॉर्ड्स

2
@PeterCordes pwdकी स्थिति में थोड़ा की उपस्थिति से समझौता है PWD, लेकिन हाँ, वह भी अंतर्निहित स्थिति का उपयोग कार्यक्षमता को बेहतर बनाने के लिए पार्टी का एक उदाहरण है
muru
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.