मुझे आज तक इस पुरस्कार के बारे में पता नहीं था जब कुछ बदमाशों ने मेरे एक जवाब के लिए मुझ पर UUOC पिन करने की कोशिश की। यह एक था cat file.txt | grep foo | cut ... | cut ...
। मैंने उसे अपने मन का एक टुकड़ा दिया, और ऐसा करने के बाद ही उसने मुझे इस पुरस्कार की उत्पत्ति और ऐसा करने की प्रथा का जिक्र किया। आगे की खोज ने मुझे इस प्रश्न की ओर अग्रसर किया। कुछ भी होश में विचार के बावजूद दुर्भाग्य से कोई भी जवाब मेरे तर्क में शामिल नहीं था।
मुझे उसे शिक्षित करते समय रक्षात्मक होने का मतलब नहीं था। आखिरकार, मेरे छोटे वर्षों में मैंने कमांड लिखी होगी grep foo file.txt | cut ... | cut ...
क्योंकि जब भी आप लगातार सिंगल grep
एस करते हैं तो आप फ़ाइल तर्क की नियुक्ति सीखते हैं और यह तैयार ज्ञान है कि पहले पैटर्न है और बाद में फ़ाइल नाम हैं।
यह एक सचेत विकल्प था जब मैंने cat
"अच्छे स्वाद" (लिनुस टॉर्वाल्ड्स के शब्दों में) के कारण आंशिक रूप से उपसर्ग के साथ सवाल का जवाब दिया, लेकिन मुख्य रूप से फ़ंक्शन के सम्मोहक कारण के लिए।
उत्तरार्द्ध कारण अधिक महत्वपूर्ण है इसलिए मैं इसे पहले बाहर कर दूंगा। जब मैं एक समाधान के रूप में एक पाइपलाइन की पेशकश करता हूं तो मुझे उम्मीद है कि यह पुन: प्रयोज्य होगा। यह काफी संभावना है कि एक पाइपलाइन को अंत में जोड़ा जाएगा या किसी अन्य पाइपलाइन में जोड़ा जाएगा। उस स्थिति में पुन: प्रयोज्यता को कम करने के लिए एक फ़ाइल तर्क रखने, और संभवतः फ़ाइल त्रुटि मौजूद होने पर त्रुटि संदेश के बिना चुपचाप ऐसा करते हैं । अर्थात। grep foo xyz | grep bar xyz | wc
आपको कितनी लाइनें xyz
मिलेंगी bar
जबकि आप उन पंक्तियों की संख्या की अपेक्षा कर रहे हैं जिनमें दोनों foo
और हैं bar
। त्रुटियों से ग्रस्त होने से पहले एक पाइपलाइन में एक कमांड के लिए तर्क को बदलना। इसे मौन विफलताओं की संभावना से जोड़ें और यह एक विशेष रूप से कपटी अभ्यास बन जाता है।
पूर्व कारण "बहुत अच्छा स्वाद" के बाद से महत्वहीन नहीं है, केवल ऊपर की मौन विफलताओं जैसी चीजों के लिए एक सहज अवचेतन तर्क है जो आप उस समय सही नहीं सोच सकते हैं जब कोई व्यक्ति शिक्षा की आवश्यकता को कहता है "लेकिन नहीं है" वह बिल्ली बेकार है ”।
हालाँकि, मैं पूर्व के "अच्छे स्वाद" के कारण भी अवगत कराने का प्रयास करूँगा जिसका मैंने उल्लेख किया है। यही कारण है कि यूनिक्स के रूढ़िवादी डिजाइन भावना के साथ करना है। grep
करता है cut
और नहीं ls
करता है grep
। इसलिए बहुत कम से कम grep foo file1 file2 file3
डिजाइन की भावना के खिलाफ जाता है। इसे करने का ऑर्थोगोनल तरीका है cat file1 file2 file3 | grep foo
। अब, grep foo file1
यह केवल एक विशेष मामला है grep foo file1 file2 file3
, और यदि आप इसका इलाज नहीं करते हैं तो आप कम से कम ब्रेन क्लॉक चक्रों का उपयोग करके बेकार बिल्ली पुरस्कार से बचने की कोशिश कर रहे हैं।
यह हमें उस तर्क की ओर ले जाता है जो grep foo file1 file2 file3
समवर्ती है, और cat
समवर्ती है, इसलिए यह उचित है, cat file1 file2 file3
लेकिन क्योंकि cat
समवर्ती नहीं है cat file1 | grep foo
इसलिए हम cat
और सर्वशक्तिमान यूनिक्स दोनों की भावना का उल्लंघन कर रहे हैं । खैर, अगर ऐसा होता तो एक फाइल के आउटपुट को पढ़ने के लिए यूनिक्स को अलग कमांड की जरूरत होती है और इसे थूकने के लिए थूकना पड़ता है (इसे पगनेट नहीं करना चाहिए या स्टैडआउट को सिर्फ एक शुद्ध थूक)। इसलिए आपके पास ऐसी स्थिति होगी जहां आप कहते हैं cat file1 file2
या आप कहते हैं dog file1
और ईमानदारी से याद रखें cat file1
कि पुरस्कार प्राप्त करने से बचने के लिए, जबकि dog file1 file2
उम्मीद है कि बचने के बाद से dog
कई फ़ाइलों को निर्दिष्ट किए जाने पर डिज़ाइन में त्रुटि हो सकती है।
उम्मीद है कि इस बिंदु पर आप यूनिक्स डिजाइनरों के साथ सहानुभूति रखते हैं, जिसमें एक अलग कमांड शामिल करने के लिए एक फाइल को स्टडआउट करने के लिए नहीं है, जबकि cat
इसे किसी अन्य नाम देने के बजाय कॉन्टेनेट करने के लिए भी नामकरण किया गया है। <edit>
इस तरह के एक कुत्ते, दुर्भाग्यपूर्ण <
ऑपरेटर है। यह आसान संरचना को रोकने के लिए पाइपलाइन के अंत में दुर्भाग्यपूर्ण है। शुरुआत में इसे रखने के लिए कोई कृत्रिम रूप से या सौंदर्य से साफ तरीका नहीं है। यह सामान्य रूप से पर्याप्त नहीं होने के कारण भी दुर्भाग्यपूर्ण है, इसलिए आप कुत्ते के साथ शुरू करते हैं लेकिन बस एक और फ़ाइल नाम जोड़ते हैं यदि आप भी चाहते हैं कि इसे पिछले एक के बाद संसाधित किया जाए। ( >
दूसरी ओर आधा खराब नहीं है। अंत में इसका लगभग सही स्थान है। यह आमतौर पर एक पाइपलाइन का पुन: उपयोग करने योग्य हिस्सा नहीं है, और तदनुसार यह प्रतीकात्मक रूप से प्रतिष्ठित है।)</edit>
अगला सवाल यह है कि ऐसे आदेश क्यों महत्वपूर्ण हैं जो केवल एक फाइल थूकते हैं या किसी फाइल को आगे बढ़ाने के लिए बिना किसी प्रोसेसिंग के स्टेपआउट करने के लिए कहते हैं? एक कारण हर एक यूनिक्स कमांड होने से बचने के लिए है जो कम से कम एक कमांड लाइन फ़ाइल तर्क को पार्स करने के लिए मानक इनपुट पर संचालित होता है और मौजूद होने पर इसे इनपुट के रूप में उपयोग करना है। दूसरा कारण उपयोगकर्ताओं को याद रखने से बचना है: (ए) जहां फ़ाइल नाम के तर्क चलते हैं; और (बी) जैसा कि ऊपर बताया गया है, साइलेंट पाइपलाइन बग से बचें।
यह हमें लाता है कि क्यों grep
अतिरिक्त तर्क है। औचित्य उपयोगकर्ता-प्रवाह के लिए आदेशों के लिए अनुमति देता है जो अक्सर और एक स्टैंड-अलोन आधार पर उपयोग किया जाता है (बजाय एक पाइपलाइन के रूप में)। यह प्रयोज्य में एक महत्वपूर्ण लाभ के लिए रूढ़िवाद का एक मामूली समझौता है। सभी कमांडों को इस तरह से डिज़ाइन नहीं किया जाना चाहिए और जो कमांड अक्सर उपयोग नहीं किए जाते हैं, उन्हें पूरी तरह से फ़ाइल तर्कों के अतिरिक्त तर्क से बचना चाहिए (याद रखें कि अतिरिक्त तर्क अनावश्यक नाजुकता (बग की संभावना))। अपवाद के मामले में जैसे फ़ाइल तर्क देने की अनुमति है grep
। (जिस तरह से ध्यान दें कि ls
न केवल स्वीकार करने के लिए एक पूरी तरह से अलग कारण है, लेकिन बहुत ज्यादा फ़ाइल तर्क की आवश्यकता है)
अंत में, जो बेहतर किया जा सकता था वह यह है कि यदि मानक इनपुट उपलब्ध हो तो ऐसी असाधारण आज्ञाएँ grep
(लेकिन आवश्यक नहीं ls
) एक त्रुटि उत्पन्न करती हैं। यह उचित है क्योंकि कमांड में तर्क शामिल हैं जो उपयोगकर्ता सुविधा के लिए सर्वशक्तिमान यूनिक्स की ऑर्थोगोनल भावना का उल्लंघन करता है। आगे उपयोगकर्ता की सुविधा के लिए, अर्थात एक मौन विफलता के कारण होने वाली पीड़ा को रोकने के लिए, इस तरह के आदेशों को उपयोगकर्ता को सचेत करने में अपने स्वयं के उल्लंघन का उल्लंघन करने में संकोच नहीं करना चाहिए यदि मौन विफलता की संभावना है।