lsइसके निष्पादन के लिए एक अलग प्रक्रिया की आवश्यकता क्यों है ? मुझे पता है कि क्यों cdतंत्र की तरह कमांडों को फोर्किंग तंत्र द्वारा निष्पादित नहीं किया जा सकता है, लेकिन क्या lsबिना फोर्किंग के निष्पादित किया जाता है?
lsइसके निष्पादन के लिए एक अलग प्रक्रिया की आवश्यकता क्यों है ? मुझे पता है कि क्यों cdतंत्र की तरह कमांडों को फोर्किंग तंत्र द्वारा निष्पादित नहीं किया जा सकता है, लेकिन क्या lsबिना फोर्किंग के निष्पादित किया जाता है?
जवाबों:
इसका उत्तर कमोबेश lsएक बाहरी निष्पादन योग्य है। आप रनिंग करके इसकी लोकेशन देख सकते हैं type -p ls।
lsशेल में क्यों नहीं बनाया गया है? खैर, यह क्यों होना चाहिए? शेल का काम हर उपलब्ध कमांड को शामिल करना नहीं है, बल्कि उन्हें चलाने में सक्षम वातावरण प्रदान करना है। कुछ आधुनिक गोले हैं echo, printfऔर उनके ilk बिल्डरों के रूप में, जो तकनीकी रूप से निर्मित नहीं होते हैं, लेकिन प्रदर्शन कारणों से बनाए जाते हैं जब वे बार-बार चलाए जाते हैं (मुख्य रूप से तंग छोरों में)। उन्हें बिना निर्माण किए, शेल को फोर्क करना होगा और उन्हें प्रत्येक कॉल के लिए एक नई प्रक्रिया निष्पादित करनी होगी, जो बेहद धीमी हो सकती है।
बहुत कम से कम, lsएक बाहरी निष्पादन योग्य, सिस्टम कॉल के निष्पादन परिवार में से एक को चलाने की आवश्यकता होती है। आप इसे बिना फोर्क किए कर सकते हैं, लेकिन यह आपके द्वारा उपयोग किए जा रहे प्राथमिक शेल को बदल देगा। आप निम्न करके उस उदाहरण में देख सकते हैं कि क्या होता है:
exec ls; echo "this never gets printed"
चूंकि आपके शेल की प्रक्रिया छवि को बदल दिया गया है, ऐसा करने के बाद वर्तमान शेल अब सुलभ नहीं है। एलएस चलाने के बाद शेल को जारी रखने में सक्षम होने के लिए, कमांड को शेल में बनाया जाना होगा।
फोर्किंग एक प्रक्रिया को बदलने की अनुमति देता है जो आपका प्राथमिक शेल नहीं है, जिसका अर्थ है कि आप बाद में अपना शेल चलाना जारी रख सकते हैं।
echo, printfआदि
cdएक बाहरी निष्पादन योग्य क्यों नहीं है?
cdPOSIX अनुरूप ऑपरेटिंग सिस्टम में निष्पादन योग्य ( यहाँ देखें )। यदि आप वर्तमान प्रक्रिया में वास्तव में chdir () चाहते हैं, हालांकि, आपको इसे शेल में निर्मित करने की आवश्यकता है।
बैश संदर्भ मैनुअल कहता है:
अंतर्निहित उपयोगिताओं को अलग-अलग उपयोगिताओं के साथ प्राप्त करने के लिए असंभव या असुविधाजनक को लागू करना आवश्यक है।
अर्थात्, शेल केवल तभी निर्मित कमांड शामिल करने के लिए डिज़ाइन किए गए हैं यदि:
lsआदेश ऊपर requirments के किसी भी मेल नहीं खाती।
हालांकि , यहां कोई प्रोग्रामिंग बाधा नहीं है lsजो अंतर्निहित के रूप में प्रत्यारोपित होने से रोकती है, जो बैश दुभाषिया के रूप में एक ही प्रक्रिया में निष्पादित हो रही है। कमांड के लिए डिज़ाइन के कारण अंतर्निहित शेल के रूप में प्रत्यारोपित नहीं किया जा रहा है:
पहले कारण के बारे में - आप चाहते हैं कि शेल यथासंभव स्वतंत्र और लचीला हो। आप नहीं चाहते कि शेल lsNFS माउंट पर अटक जाए , जो "अभी भी कोशिश नहीं कर रहा है"।
दूसरे कारण के बारे में - कई उदाहरणों में आप एक ऐसे सिस्टम के लिए एक शेल का उपयोग करना चाह सकते हैं जो किसी भिन्न lsकार्यान्वयन वाले बिजीबॉक्स या अन्य फाइल सिस्टम का उपयोग करता है । या यहां तक कि ओएस के समान शेल स्रोत का उपयोग करें जिसमें अलग-अलग lsकार्यान्वयन हैं।
तीसरे कारण के बारे में - एक अभिव्यक्ति के लिए जैसे कि शेल दुभाषिया के रूप में एक ही प्रक्रिया में find . -type d | xargs ls -ladलागू करना मुश्किल या असंभव होगा ls।
चौथे कारण के बारे में - कुछ lsआज्ञाओं को पूरा होने में लंबा समय लग सकता है। आप चाहते हैं कि इस बीच शेल कुछ और जारी रखे।
नोट: देखें यह उपयोगी पोस्ट द्वारा वॉरेन युवा एक ऐसी ही सवाल के जवाब में।
lsप्रक्रिया जैसे बाहरी प्रक्रिया में पाइप करता है। यह किया जा सकता है, लेकिन यह जटिल होगा।
bashआउटपुट alias | grep ls। इनपुटcat /etc/passwd | while read a; do echo "$a"; done
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एक समान कार्य कर सकता है।
मुझे लगता है कि कुछ लोग यहां गायब हैं, 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का एक लंबा विकास चक्र रहा है और जो परिणाम प्रदर्शित होते हैं उसे कैसे अनुकूलित करने के लिए विकल्प लागू हो सकते हैं। डिफ़ॉल्ट रूप से एक अंतर्निहित एलएस का उपयोग करना या तो इस कार्यक्षमता को खो देगा या शेल जटिलता और आकार में काफी वृद्धि करेगा।
यह वही है जो आप देख रहे हैं:
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
lsएक बाहरी कार्यक्रम है,echo *याecho * .*(शेल विकल्पों पर निर्भर करता है) फोर्किंग के बिना फाइलों को सूचीबद्ध करने का एक बहुत अच्छा काम करता है।