"Ls" को क्रियान्वित करने के लिए एक अलग प्रक्रिया की आवश्यकता क्यों है?


14

lsइसके निष्पादन के लिए एक अलग प्रक्रिया की आवश्यकता क्यों है ? मुझे पता है कि क्यों cdतंत्र की तरह कमांडों को फोर्किंग तंत्र द्वारा निष्पादित नहीं किया जा सकता है, लेकिन क्या lsबिना फोर्किंग के निष्पादित किया जाता है?


1
यद्यपि lsएक बाहरी कार्यक्रम है, echo *या echo * .*(शेल विकल्पों पर निर्भर करता है) फोर्किंग के बिना फाइलों को सूचीबद्ध करने का एक बहुत अच्छा काम करता है।
जेरिट

यह और भी बेहतर है: प्रिंटफ "% s \ n" *
कोस्टा

शैल विविधता नोट: tcsh में एक बिलिन होता है ls-Fजो जैसा कार्य करता है ls -F। यह दक्षता के लिए है। आपको हमेशा -Fवही मिलता है जो आमतौर पर एक अच्छा विचार होता है। यदि आप किसी अन्य विकल्प को निर्दिष्ट करते हैं तो यह बाहरी कमांड को दंडित करता है।

जवाबों:


18

इसका उत्तर कमोबेश lsएक बाहरी निष्पादन योग्य है। आप रनिंग करके इसकी लोकेशन देख सकते हैं type -p ls

lsशेल में क्यों नहीं बनाया गया है? खैर, यह क्यों होना चाहिए? शेल का काम हर उपलब्ध कमांड को शामिल करना नहीं है, बल्कि उन्हें चलाने में सक्षम वातावरण प्रदान करना है। कुछ आधुनिक गोले हैं echo, printfऔर उनके ilk बिल्डरों के रूप में, जो तकनीकी रूप से निर्मित नहीं होते हैं, लेकिन प्रदर्शन कारणों से बनाए जाते हैं जब वे बार-बार चलाए जाते हैं (मुख्य रूप से तंग छोरों में)। उन्हें बिना निर्माण किए, शेल को फोर्क करना होगा और उन्हें प्रत्येक कॉल के लिए एक नई प्रक्रिया निष्पादित करनी होगी, जो बेहद धीमी हो सकती है।

बहुत कम से कम, lsएक बाहरी निष्पादन योग्य, सिस्टम कॉल के निष्पादन परिवार में से एक को चलाने की आवश्यकता होती है। आप इसे बिना फोर्क किए कर सकते हैं, लेकिन यह आपके द्वारा उपयोग किए जा रहे प्राथमिक शेल को बदल देगा। आप निम्न करके उस उदाहरण में देख सकते हैं कि क्या होता है:

exec ls; echo "this never gets printed"

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

फोर्किंग एक प्रक्रिया को बदलने की अनुमति देता है जो आपका प्राथमिक शेल नहीं है, जिसका अर्थ है कि आप बाद में अपना शेल चलाना जारी रख सकते हैं।


1
मुझे लगता है कि वह पूछ रहा है कि ls (1) गोले की एक अंतर्निहित विशेषता क्यों नहीं है, जिसे किसी को यह समझाने की आवश्यकता होगी कि विभिन्न विक्रेताओं के पास ls (1) के लिए अलग-अलग विकल्प कैसे हैं और फाइलसिस्टम से अलग सामान को क्वेरी करने में सक्षम है, आदि और भी। अप, और ज्यादातर यह 'निर्मित' खोल होने के चढ़ाव।
llua

@llua मुझे लगता है कि बारे में कुछ जानकारी है, और के अपवाद के मामलों जोड़ा echo, printfआदि
क्रिस नीचे

यह हमेशा स्पष्ट नहीं होता है कि कुछ चीजें निर्मित क्यों हैं और अन्य नहीं हैं। उदाहरण के लिए, cdएक बाहरी निष्पादन योग्य क्यों नहीं है?
फहीम मीठा

@FaheemMitha वहाँ है एक बाहरी cdPOSIX अनुरूप ऑपरेटिंग सिस्टम में निष्पादन योग्य ( यहाँ देखें )। यदि आप वर्तमान प्रक्रिया में वास्तव में chdir () चाहते हैं, हालांकि, आपको इसे शेल में निर्मित करने की आवश्यकता है।
क्रिस डाउन

यह एक आदत बन गई है कि lsबाहरी क्यों है, लेकिन इसे एक शेल में भी लागू किया जा सकता है। बिजीबॉक्स देखें।

15

बैश संदर्भ मैनुअल कहता है:

अंतर्निहित उपयोगिताओं को अलग-अलग उपयोगिताओं के साथ प्राप्त करने के लिए असंभव या असुविधाजनक को लागू करना आवश्यक है।

अर्थात्, शेल केवल तभी निर्मित कमांड शामिल करने के लिए डिज़ाइन किए गए हैं यदि:

  1. POSIX मानक द्वारा आवश्यक
  2. ऐसे कमांड जिन्हें शेल की पहुंच की आवश्यकता होती है, जैसे कि जॉब कंट्रोल बिल्ट-इन
  3. ऐसे कमांड जो बहुत ही सरल हैं, ओएस पर निर्भर नहीं हैं और जब इन-प्रिंट के रूप में बिल्ट-इन के रूप में कार्यान्वित किया जाता है, तो निष्पादन दक्षता में वृद्धि होती है

lsआदेश ऊपर requirments के किसी भी मेल नहीं खाती।

हालांकि , यहां कोई प्रोग्रामिंग बाधा नहीं है lsजो अंतर्निहित के रूप में प्रत्यारोपित होने से रोकती है, जो बैश दुभाषिया के रूप में एक ही प्रक्रिया में निष्पादित हो रही है। कमांड के लिए डिज़ाइन के कारण अंतर्निहित शेल के रूप में प्रत्यारोपित नहीं किया जा रहा है:

  1. शेल को फ़ाइल सिस्टम से अलग होना चाहिए - कोई अंतर्निहित कमांड किसी भी फाइल सिस्टम या परिधीय उपकरणों के सही संचालन पर निर्भर नहीं होना चाहिए
  2. एक कमांड जो कि फाइलसिस्टम टाइप हो सकती है या ओएस आश्रित एक अलग निष्पादन योग्य होनी चाहिए
  3. एक कमांड जिसे आप पाइप करना चाहते हैं या उससे अलग प्रक्रिया होनी चाहिए
  4. एक कमांड जिसे आप पृष्ठभूमि में चलाना चाहते हैं, एक अलग निष्पादन योग्य होना चाहिए
  5. एक कमांड जिसमें बड़ी संख्या में संभावित पैरामीटर हैं, एक अलग निष्पादन योग्य में बेहतर तरीके से कार्यान्वित किया जाता है
  6. जिन कमांडों में समान आउटपुट होना चाहिए, चाहे वे किस प्रकार के शेल (बैश, csh, tsh, ...) को आमंत्रित करते हों, उन्हें स्टैंड-अलोन एक्ज़ीक्यूटेबल होना चाहिए

पहले कारण के बारे में - आप चाहते हैं कि शेल यथासंभव स्वतंत्र और लचीला हो। आप नहीं चाहते कि शेल lsNFS माउंट पर अटक जाए , जो "अभी भी कोशिश नहीं कर रहा है"।

दूसरे कारण के बारे में - कई उदाहरणों में आप एक ऐसे सिस्टम के लिए एक शेल का उपयोग करना चाह सकते हैं जो किसी भिन्न lsकार्यान्वयन वाले बिजीबॉक्स या अन्य फाइल सिस्टम का उपयोग करता है । या यहां तक ​​कि ओएस के समान शेल स्रोत का उपयोग करें जिसमें अलग-अलग lsकार्यान्वयन हैं।

तीसरे कारण के बारे में - एक अभिव्यक्ति के लिए जैसे कि शेल दुभाषिया के रूप में एक ही प्रक्रिया में find . -type d | xargs ls -ladलागू करना मुश्किल या असंभव होगा ls

चौथे कारण के बारे में - कुछ lsआज्ञाओं को पूरा होने में लंबा समय लग सकता है। आप चाहते हैं कि इस बीच शेल कुछ और जारी रखे।


नोट: देखें यह उपयोगी पोस्ट द्वारा वॉरेन युवा एक ऐसी ही सवाल के जवाब में।


आप पाइपिंग आउटपुट में आसानी से चूक गए अगर इसकी एक अलग कमांड, और सभी प्रोग्रामिंग यह एक शेल प्राइमेट को एक अलग निष्पादन योग्य में पाइप करने के लिए ले जाएगा।
ब्रूस एडिगर

@BruceEdiger: सम्मानित बीई से एक टिप्पणी प्राप्त करने के लिए क्या खुशी है। धन्यवाद! मेरा मानना ​​है कि कारण 3 में आपकी टिप्पणी शामिल है, नहीं?
जोनाथन बेन-अवराम 13

1
मैं इस बारे में अधिक सोच रहा था कि शेल का स्रोत कोड स्वयं कितना जटिल होगा अगर उसे बाहरी प्रक्रियाओं के लिए पाइप को संभालना पड़ता है, और एक आंतरिक कमांड के आउटपुट को काल्पनिक lsप्रक्रिया जैसे बाहरी प्रक्रिया में पाइप करता है। यह किया जा सकता है, लेकिन यह जटिल होगा।
ब्रूस एडिगर

1
मुझे सबसे ज्यादा डर लगता है अगर आपके सभी 5 पॉइंट्स म्यूट नहीं हैं। 1: ls (उम्मीद है) फ़ाइल सिस्टम कार्यान्वयन से स्वतंत्र है। यह मानक पुस्तकालय और अनुप्रयोगों के लिए एक सुसंगत इंटरफ़ेस प्रदान करने के लिए कर्नेल पर निर्भर है। 2: एल एस संभवतः शेल की तुलना में ओएस पर कम निर्भर है। 3: गोले निश्चित रूप से पाइपलाइनों में बिलिन की अनुमति देता है। 4: गोले निश्चित रूप से बिल्डरों को पृष्ठभूमि में चलाने की अनुमति देते हैं। 5: यह काफी व्यक्तिपरक है।
जुलैग्रे

1
@ JonathanBen-Avraham @BruceEdiger शेल पहले से ही सब-हेल्‍थ वाले बिलिंस के लिए पाइप केस नहीं संभालते हैं? उदा bashआउटपुट alias | grep ls। इनपुटcat /etc/passwd | while read a; do echo "$a"; done
मैट

2

lsएक अलग प्रक्रिया की आवश्यकता नहीं है। बहुत कम आदेशों को वास्तव में एक अलग प्रक्रिया की आवश्यकता होती है: केवल उन लोगों को जो विशेषाधिकारों को बदलने की आवश्यकता है।

एक नियम के रूप में, शेल आदेशों को बिल्डिंस के रूप में केवल तभी लागू करते हैं जब उन आदेशों को बिल्डिंस के रूप में लागू करने की आवश्यकता होती है। आदेश की तरह alias, cd, exit, export, jobs, ... पढ़ने के लिए या खोल के कुछ आंतरिक स्थिति को संशोधित करने, और इसलिए जरूरत नहीं अलग कार्यक्रमों हो सकता है। जिन कमांडों में ऐसी कोई आवश्यकता नहीं है, वे अलग-अलग कमांड हो सकते हैं; इस तरह, उन्हें किसी भी शेल या अन्य प्रोग्राम से बुलाया जा सकता है।

बैश में बिलिंस की सूची को देखते हुए, केवल निम्नलिखित बिल्डरों को अलग-अलग कमांड के रूप में लागू किया जा सकता है। उनमें से कुछ के लिए, कार्यक्षमता का मामूली नुकसान होगा।

  • command- लेकिन यह उन परिस्थितियों में अपनी उपयोगिता खो देगा जहां PATHठीक से स्थापित नहीं किया जा सकता है और स्क्रिप्ट commandइसे स्थापित करने के हिस्से के रूप में उपयोग कर रही है।
  • echo - यह दक्षता के लिए एक अंतर्निहित है।
  • help - यह एक अलग डेटाबेस का उपयोग कर सकता है, लेकिन शेल निष्पादन योग्य में सहायता पाठ को एम्बेड करने से शेल निष्पादन योग्य आत्म-निहित बनाने का लाभ होता है।
  • kill - एक बेसिन होने में दो फायदे हैं: यह प्रक्रिया आईडी के अलावा नौकरी के पदनामों को पहचान सकता है, और इसका उपयोग तब भी किया जा सकता है जब एक अलग प्रक्रिया शुरू करने के लिए पर्याप्त संसाधन नहीं हैं।
  • printf- एक ही कारण के लिए echo, और -vएक चर में आउटपुट डालने के विकल्प का समर्थन करने के लिए भी ।
  • pwd - बिलिन तार्किक वर्तमान निर्देशिका ट्रैकिंग की अतिरिक्त क्षमता प्रदान करता है (उन्हें विस्तारित करने के बजाय प्रतीकात्मक लिंक को बरकरार रखना)।
  • test- यह दक्षता के लिए एक अंतर्निहित है (और बैश भी /dev/fd/…कुछ ऑपरेटिंग सिस्टम पर फ़ाइलों के साथ कुछ जादू करता है )।

कुछ गोले एक अतिरिक्त संख्या में अतिरिक्त निर्मिती प्रदान करते हैं। नहीं है सैश , जो एक खोल आपातकालीन मरम्मत के लिए एकमात्र बाइनरी (जब कुछ बाहरी आदेशों प्रयोग करने योग्य नहीं हो सकता है) होने के लिए बनाया है। यह एक अंतर्निहित ls, कहा जाता -lsहै, साथ ही इस तरह के रूप में अन्य उपकरणों -grepऔर -tar। सैश के बिल्डरों में पूर्ण-कमांड की तुलना में कम क्षमताएं हैं। Zsh अपने zsh / files मॉड्यूल में कुछ इसी तरह के बिल्डिंग्स प्रदान करता है । यह नहीं है ls, लेकिन वाइल्डकार्ड विस्तार ( echo *) और zstatएक समान कार्य कर सकता है।


2

मुझे लगता है कि कुछ लोग यहां गायब हैं, lsलिनक्स पर जीएनयू कार्यक्रम की कतरनी जटिलता है । के निष्पादन योग्य आकार की तुलना lsकरने के लिए bashऔर dashमेरी डेबियन सिस्टम पर गोले, हम देखते हैं कि यह काफी बड़ी है:

graeme@graeme:~$ ls -lh /bin/{ls,bash,dash}
-rwxr-xr-x 1 root root 953K Mar 30  2013 /bin/bash
-rwxr-xr-x 1 root root 115K Dec 25 20:25 /bin/dash
-rwxr-xr-x 1 root root 108K Jul 20 22:52 /bin/ls

एक भी शामिल है lsपूर्ण में जीएनयू संस्करण के रूप में चित्रित के रूप में bash10% से निष्पादन योग्य आकार में वृद्धि होगी। यह लगभग पूर्ण dashशेल के आकार जैसा है !

अधिकांश शेल बिल्डरों को चुना जाता है क्योंकि वे शेल को इस तरह से एकीकृत करते हैं कि बाहरी निष्पादक नहीं कर सकते हैं (प्रश्न इंगित करता है cd, लेकिन एक और उदाहरण killबैश नौकरी नियंत्रण के साथ एकीकरण का संस्करण है ) या क्योंकि वे लागू करने के लिए बहुत सरल आदेश हैं, एक बड़ी गति बनाम आकार का भुगतान देना ( trueऔर falseयह जितना सरल होता है)।

GNU lsका एक लंबा विकास चक्र रहा है और जो परिणाम प्रदर्शित होते हैं उसे कैसे अनुकूलित करने के लिए विकल्प लागू हो सकते हैं। डिफ़ॉल्ट रूप से एक अंतर्निहित एलएस का उपयोग करना या तो इस कार्यक्षमता को खो देगा या शेल जटिलता और आकार में काफी वृद्धि करेगा।


1

cdशेल में बनाया गया है, lsएक अलग कार्यक्रम है जिसे आप देखेंगे /bin/ls


0

यह वही है जो आप देख रहे हैं:

printf "%s\n" *

इसके अलावा आप फ़ाइल नाम सरणी में संग्रहीत कर सकते हैं:

files=(`printf "%s\n" *`)  #items are separated by whitespace
echo ${#files[*]} files
for index in ${!a[*]}
do printf "%d: %s\n" $index ${a[$index]};
done

लेकिन यह नामों के रिक्त स्थान की परवाह नहीं करता है।
यह चर को पार करता है और रिक्त स्थान की परवाह करता है:

printf "%s\n" * | while read a; do echo $a; done
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.