बाहरी कार्यान्वयन करने के लिए POSIX को कुछ शेल बिल्ट-इन की आवश्यकता क्यों होती है?


19

से के बारे में है कि क्या printf है इस सवाल का एक यश के लिए अंतर्निहित , आता है यह जवाब है कि उद्धरण POSIX मानक

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

आंतरिक कार्यान्वयन को चलाने से पहले POSIX को बाहरी कार्यान्वयन की आवश्यकता क्यों होती है?

ऐसा लगता है ... मनमाना, इसलिए मैं उत्सुक हूं।


मेरा मानना ​​है कि यदि वांछित / आवश्यक है, तो बिल्डरों को सक्षम / अक्षम करने का एक तरीका है।
इसहाक

2
बाहरी कार्यान्वयन को हटाकर अंतर्निहित में अक्षम करना? अब नाम के आदेश printfउपलब्ध नहीं हैं।
स्टडोग

@studog, इसलिए बिल्ट-इन के समान नाम के साथ एक खाली फ़ाइल बनाएं, निष्पादित बिट को चालू करें, और इसे अपने PATH में एक निर्देशिका में डालें। : पी
वाइल्डकार्ड

@Wildcard एक कड़ाई से अनुपालन करने वाला खोल तब खोज करते समय नाम देखेगा PATHऔर फिर अंतर्निहित उपयोगिता को कॉल करेगा, न कि बाहरी स्क्रिप्ट को। क्या होगा यदि आप अपने मार्ग में बाहरी स्क्रिप्ट को कॉल करना चाहते हैं? हम्म ... यह विभिन्न संभावनाओं का वर्णन करने वाली तालिका के लिए कॉल करने के लिए लगता है। यहाँ एक है , लेकिन यह मेरे लिए कोई मतलब नहीं है।
Kusalananda

@ कुसलानंद, अपना पहला वाक्य, यही मेरी बात थी। इसलिए मैंने खाली फाइल बनाने के लिए क्यों कहा ।
वाइल्डकार्ड

जवाबों:


15

यह एक "के रूप में अगर" नियम है।

सीधे शब्दों में कहें: उपयोगकर्ताओं द्वारा देखे जाने पर शेल का व्यवहार बदल नहीं सकता है यदि कार्यान्वयन एक मानक बाहरी कमांड को शेल-इन-इन के रूप में भी उपलब्ध कराने का निर्णय लेता है।

इसके विपरीत जो मैंने /unix//a/496291/5132 पर (एक ओर) पीडी कॉर्न, मीरबीडीस कोर्न, और हिरलूम बॉर्न गोले के व्यवहारों के बीच दिखाया था ; (दूसरी ओर) जेड, 93 कोर्न, बॉर्न अगेन, और डेबियन अल्मक्विस्ट गोले; और (ग्रिपिंग हैंड पर) वतनबे शेल ने इस पर प्रकाश डाला।

गोले की जरूरत नहीं है कि के लिए printfके रूप में एक में निर्मित, को हटाने /usr/binसे PATHकी एक मंगलाचरण बनाता है printfकाम करना बंद कर। POSIX अनुरूप व्यवहार, वातानाबे खोल द्वारा अपने अनुरूप मोड में प्रदर्शित किया जाता है, उसी परिणाम का कारण बनता है। शेल का व्यवहार जिसमें एक printfअंतर्निहित है, जैसे कि यह एक बाहरी कमांड को लागू कर रहा हो।

जबकि सभी गैर-अनुरूप गोले के व्यवहार /usr/binको हटा दिया जाता है PATH, तो वे बदल नहीं जाते हैं , और वे ऐसा व्यवहार नहीं करते हैं जैसे कि वे एक बाहरी आदेश को लागू कर रहे थे।

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

(जैसा कि /unix//a/448799/5132 पर बताया गया है , वर्षों पहले लोगों ने अपने यूनिक्स के व्यक्तित्व को बदलकर चुना था कि यह क्या था PATH।)

कोई भी यह कह सकता है कि कमांड को हमेशा इस बात पर ध्यान दिए बिना काम करना चाहिए कि क्या यह पाया जा सकता PATH है, वास्तव में बाहरी कमांड को सामान्य रूप से बनाने की बात है। (यही कारण है कि मेरे नोश टूलसेट ने printenvवास्तव में संस्करण 1.38 में एक अंतर्निहित कमांड प्राप्त की । हालांकि यह एक शेल नहीं है।)

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

आगे की पढाई


13

यह काफी बेतुका है और इसीलिए कोई भी शेल इसे अपने डिफ़ॉल्ट मोड में लागू नहीं कर रहा है।

मानक के औचित्य और इसके उदाहरण से पता चलता है कि यह एक पथप्रदर्शक है जो एक नियमित रूप से अंतर्निहित पथ के साथ जुड़ा हुआ है, और उपयोगकर्ता को अपने स्वयं के द्विआधारी में प्रकट होने से पहले इसे ओवरराइड करने देते हैं PATH(उदाहरण के लिए, printfअंतर्निहित अंतर्निर्मित । बाहरी कमांड द्वारा सेटिंग द्वारा /usr/bin/printfओवरराइड किया जा सकता है )।/foo/bin/printfPATH=/foo/bin:$PATH

हालाँकि, मानक को समाप्त करने की आवश्यकता नहीं थी, लेकिन कुछ पूरी तरह से अलग (और भी बेकार और अप्रत्याशित)।

आप इस बग रिपोर्ट में इसके बारे में अधिक पढ़ सकते हैं । अंतिम स्वीकृत पाठ से उद्धरण :

कई मौजूदा कार्यान्वयन एक नियमित रूप से अंतर्निहित पैथ खोज को निष्पादित किए बिना निष्पादित करते हैं। यह व्यवहार मानक पाठ से मेल नहीं खाता है, और यह स्क्रिप्ट लेखकों को विशेष रूप से तैयार किए गए पैठ के माध्यम से नियमित रूप से निर्मित उपयोगिताओं को ओवरराइड करने की अनुमति नहीं देता है। इसके अलावा, औचित्य बताते हैं कि इरादा लेखकों को PATH को संशोधित करके अंतर्निहित को ओवरराइड करने की अनुमति देना है , लेकिन यह वह नहीं है जो प्रामाणिक पाठ कहता है

एफडब्ल्यूआईडब्ल्यू, मुझे नहीं लगता कि स्वीकृत पाठ से संशोधित आवश्यकताओं को लागू करने वाला कोई भी शेल है।


Article.gmane.org/gmane.comp.standards.posix.austin.general/… (और वहाँ कई अन्य लोग भी हैं) पर चर्चा देखें ।
स्टीफन चेज़लस


नहीं, (जैसे। एक प्रिंटफ अंतर्निहित / usr / bin / printf के साथ PATH = / foo / bin: $ PATH सेट करके / foo / bin / printf बाहरी कमांड द्वारा ओवरराइड किया जा सकता है)। , यह गलत है। PATH में /usr/bin/printfया तो / दोनों में से किसी का भी अस्तित्व अंतर्निहित प्रिंटफ /foo/bin/printfको सक्रिय करेगा । केवल एक चीज जो बाहरी (पाथ में) बाहरी है वह बिलिन को अक्षम करना है। ( युक्ति के पत्र द्वारा )। printf
इसहाक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.