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
एक बाहरी निष्पादन योग्य क्यों नहीं है?
cd
POSIX अनुरूप ऑपरेटिंग सिस्टम में निष्पादन योग्य ( यहाँ देखें )। यदि आप वर्तमान प्रक्रिया में वास्तव में chdir () चाहते हैं, हालांकि, आपको इसे शेल में निर्मित करने की आवश्यकता है।
बैश संदर्भ मैनुअल कहता है:
अंतर्निहित उपयोगिताओं को अलग-अलग उपयोगिताओं के साथ प्राप्त करने के लिए असंभव या असुविधाजनक को लागू करना आवश्यक है।
अर्थात्, शेल केवल तभी निर्मित कमांड शामिल करने के लिए डिज़ाइन किए गए हैं यदि:
ls
आदेश ऊपर requirments के किसी भी मेल नहीं खाती।
हालांकि , यहां कोई प्रोग्रामिंग बाधा नहीं है ls
जो अंतर्निहित के रूप में प्रत्यारोपित होने से रोकती है, जो बैश दुभाषिया के रूप में एक ही प्रक्रिया में निष्पादित हो रही है। कमांड के लिए डिज़ाइन के कारण अंतर्निहित शेल के रूप में प्रत्यारोपित नहीं किया जा रहा है:
पहले कारण के बारे में - आप चाहते हैं कि शेल यथासंभव स्वतंत्र और लचीला हो। आप नहीं चाहते कि शेल ls
NFS माउंट पर अटक जाए , जो "अभी भी कोशिश नहीं कर रहा है"।
दूसरे कारण के बारे में - कई उदाहरणों में आप एक ऐसे सिस्टम के लिए एक शेल का उपयोग करना चाह सकते हैं जो किसी भिन्न 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
पूर्ण में जीएनयू संस्करण के रूप में चित्रित के रूप में bash
10% से निष्पादन योग्य आकार में वृद्धि होगी। यह लगभग पूर्ण 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 * .*
(शेल विकल्पों पर निर्भर करता है) फोर्किंग के बिना फाइलों को सूचीबद्ध करने का एक बहुत अच्छा काम करता है।